xref: /OK3568_Linux_fs/kernel/drivers/input/touchscreen/gt1x/gt1x.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* drivers/input/touchscreen/gt1x.c
2*4882a593Smuzhiyun  *
3*4882a593Smuzhiyun  * 2010 - 2014 Goodix Technology.
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * This program is free software; you can redistribute it and/or modify
6*4882a593Smuzhiyun  * it under the terms of the GNU General Public License as published by
7*4882a593Smuzhiyun  * the Free Software Foundation; either version 2 of the License, or
8*4882a593Smuzhiyun  * (at your option) any later version.
9*4882a593Smuzhiyun  *
10*4882a593Smuzhiyun  * This program is distributed in the hope that it will be a reference
11*4882a593Smuzhiyun  * to you, when you are integrating the GOODiX's CTP IC into your system,
12*4882a593Smuzhiyun  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13*4882a593Smuzhiyun  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14*4882a593Smuzhiyun  * General Public License for more details.
15*4882a593Smuzhiyun  *
16*4882a593Smuzhiyun  * Version: 1.4
17*4882a593Smuzhiyun  * Release Date:  2015/07/10
18*4882a593Smuzhiyun  */
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun #include <linux/irq.h>
21*4882a593Smuzhiyun #include "gt1x.h"
22*4882a593Smuzhiyun #include <linux/input/mt.h>
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun static struct work_struct gt1x_work;
25*4882a593Smuzhiyun static struct input_dev *input_dev;
26*4882a593Smuzhiyun static struct workqueue_struct *gt1x_wq;
27*4882a593Smuzhiyun static const char *gt1x_ts_name = "goodix-ts";
28*4882a593Smuzhiyun static const char *input_dev_phys = "input/ts";
29*4882a593Smuzhiyun #ifdef CONFIG_PM
30*4882a593Smuzhiyun static const struct dev_pm_ops gt1x_ts_pm_ops;
31*4882a593Smuzhiyun #endif
32*4882a593Smuzhiyun #ifdef GTP_CONFIG_OF
33*4882a593Smuzhiyun bool gt1x_gt5688;
34*4882a593Smuzhiyun int gt1x_rst_gpio;
35*4882a593Smuzhiyun int gt1x_int_gpio;
36*4882a593Smuzhiyun static bool power_invert;
37*4882a593Smuzhiyun #endif
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun static int gt1x_register_powermanger(void);
40*4882a593Smuzhiyun static int gt1x_unregister_powermanger(void);
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun /**
43*4882a593Smuzhiyun  * gt1x_i2c_write - i2c write.
44*4882a593Smuzhiyun  * @addr: register address.
45*4882a593Smuzhiyun  * @buffer: data buffer.
46*4882a593Smuzhiyun  * @len: the bytes of data to write.
47*4882a593Smuzhiyun  *Return: 0: success, otherwise: failed
48*4882a593Smuzhiyun  */
gt1x_i2c_write(u16 addr,u8 * buffer,s32 len)49*4882a593Smuzhiyun s32 gt1x_i2c_write(u16 addr, u8 *buffer, s32 len)
50*4882a593Smuzhiyun {
51*4882a593Smuzhiyun 	struct i2c_msg msg = {
52*4882a593Smuzhiyun 		.flags = 0,
53*4882a593Smuzhiyun 		.addr = gt1x_i2c_client->addr,
54*4882a593Smuzhiyun 	};
55*4882a593Smuzhiyun 	return _do_i2c_write(&msg, addr, buffer, len);
56*4882a593Smuzhiyun }
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun /**
59*4882a593Smuzhiyun  * gt1x_i2c_read - i2c read.
60*4882a593Smuzhiyun  * @addr: register address.
61*4882a593Smuzhiyun  * @buffer: data buffer.
62*4882a593Smuzhiyun  * @len: the bytes of data to write.
63*4882a593Smuzhiyun  *Return: 0: success, otherwise: failed
64*4882a593Smuzhiyun  */
gt1x_i2c_read(u16 addr,u8 * buffer,s32 len)65*4882a593Smuzhiyun s32 gt1x_i2c_read(u16 addr, u8 *buffer, s32 len)
66*4882a593Smuzhiyun {
67*4882a593Smuzhiyun 	u8 addr_buf[GTP_ADDR_LENGTH] = { (addr >> 8) & 0xFF, addr & 0xFF };
68*4882a593Smuzhiyun 	struct i2c_msg msgs[2] = {
69*4882a593Smuzhiyun 		{
70*4882a593Smuzhiyun 		 .addr = gt1x_i2c_client->addr,
71*4882a593Smuzhiyun 		 .flags = 0,
72*4882a593Smuzhiyun 		 .buf = addr_buf,
73*4882a593Smuzhiyun 		 .len = GTP_ADDR_LENGTH},
74*4882a593Smuzhiyun 		{
75*4882a593Smuzhiyun 		 .addr = gt1x_i2c_client->addr,
76*4882a593Smuzhiyun 		 .flags = I2C_M_RD}
77*4882a593Smuzhiyun 	};
78*4882a593Smuzhiyun 	return _do_i2c_read(msgs, addr, buffer, len);
79*4882a593Smuzhiyun }
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun static spinlock_t irq_lock;
82*4882a593Smuzhiyun static s32 irq_is_disable;
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun /**
85*4882a593Smuzhiyun  * gt1x_irq_enable - enable irq function.
86*4882a593Smuzhiyun  *
87*4882a593Smuzhiyun  */
gt1x_irq_enable(void)88*4882a593Smuzhiyun void gt1x_irq_enable(void)
89*4882a593Smuzhiyun {
90*4882a593Smuzhiyun 	unsigned long irqflags = 0;
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun 	GTP_DEBUG_FUNC();
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun 	spin_lock_irqsave(&irq_lock, irqflags);
95*4882a593Smuzhiyun 	if (irq_is_disable) {
96*4882a593Smuzhiyun 		enable_irq(gt1x_i2c_client->irq);
97*4882a593Smuzhiyun 		irq_is_disable = 0;
98*4882a593Smuzhiyun 	}
99*4882a593Smuzhiyun 	spin_unlock_irqrestore(&irq_lock, irqflags);
100*4882a593Smuzhiyun }
101*4882a593Smuzhiyun 
102*4882a593Smuzhiyun /**
103*4882a593Smuzhiyun  * gt1x_irq_enable - disable irq function.
104*4882a593Smuzhiyun  *
105*4882a593Smuzhiyun  */
gt1x_irq_disable(void)106*4882a593Smuzhiyun void gt1x_irq_disable(void)
107*4882a593Smuzhiyun {
108*4882a593Smuzhiyun 	unsigned long irqflags;
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun 	GTP_DEBUG_FUNC();
111*4882a593Smuzhiyun 
112*4882a593Smuzhiyun 	spin_lock_irqsave(&irq_lock, irqflags);
113*4882a593Smuzhiyun 	if (!irq_is_disable) {
114*4882a593Smuzhiyun 		irq_is_disable = 1;
115*4882a593Smuzhiyun 		disable_irq_nosync(gt1x_i2c_client->irq);
116*4882a593Smuzhiyun 	}
117*4882a593Smuzhiyun 	spin_unlock_irqrestore(&irq_lock, irqflags);
118*4882a593Smuzhiyun }
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun #ifndef GTP_CONFIG_OF
gt1x_power_switch(s32 state)121*4882a593Smuzhiyun int gt1x_power_switch(s32 state)
122*4882a593Smuzhiyun {
123*4882a593Smuzhiyun     return 0;
124*4882a593Smuzhiyun }
125*4882a593Smuzhiyun #endif
126*4882a593Smuzhiyun 
gt1x_debug_proc(u8 * buf,int count)127*4882a593Smuzhiyun int gt1x_debug_proc(u8 *buf, int count)
128*4882a593Smuzhiyun {
129*4882a593Smuzhiyun 	return -1;
130*4882a593Smuzhiyun }
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun #if GTP_CHARGER_SWITCH
gt1x_get_charger_status(void)133*4882a593Smuzhiyun u32 gt1x_get_charger_status(void)
134*4882a593Smuzhiyun {
135*4882a593Smuzhiyun #error Need to get charger status of your platform.
136*4882a593Smuzhiyun }
137*4882a593Smuzhiyun #endif
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun /**
140*4882a593Smuzhiyun  * gt1x_ts_irq_handler - External interrupt service routine for interrupt mode.
141*4882a593Smuzhiyun  * @irq:  interrupt number.
142*4882a593Smuzhiyun  * @dev_id: private data pointer.
143*4882a593Smuzhiyun  * Return: Handle Result.
144*4882a593Smuzhiyun  *  		IRQ_HANDLED: interrupt handled successfully
145*4882a593Smuzhiyun  */
gt1x_ts_irq_handler(int irq,void * dev_id)146*4882a593Smuzhiyun static irqreturn_t gt1x_ts_irq_handler(int irq, void *dev_id)
147*4882a593Smuzhiyun {
148*4882a593Smuzhiyun 	GTP_DEBUG_FUNC();
149*4882a593Smuzhiyun 	gt1x_irq_disable();
150*4882a593Smuzhiyun 	queue_work(gt1x_wq, &gt1x_work);
151*4882a593Smuzhiyun 	return IRQ_HANDLED;
152*4882a593Smuzhiyun }
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun /**
155*4882a593Smuzhiyun  * gt1x_touch_down - Report touch point event .
156*4882a593Smuzhiyun  * @id: trackId
157*4882a593Smuzhiyun  * @x:  input x coordinate
158*4882a593Smuzhiyun  * @y:  input y coordinate
159*4882a593Smuzhiyun  * @w:  input pressure
160*4882a593Smuzhiyun  * Return: none.
161*4882a593Smuzhiyun  */
gt1x_touch_down(s32 x,s32 y,s32 size,s32 id)162*4882a593Smuzhiyun void gt1x_touch_down(s32 x, s32 y, s32 size, s32 id)
163*4882a593Smuzhiyun {
164*4882a593Smuzhiyun #if GTP_CHANGE_X2Y
165*4882a593Smuzhiyun 	GTP_SWAP(x, y);
166*4882a593Smuzhiyun #endif
167*4882a593Smuzhiyun 
168*4882a593Smuzhiyun 	if (gt1x_ics_slot_report) {
169*4882a593Smuzhiyun 		input_mt_slot(input_dev, id);
170*4882a593Smuzhiyun 		input_report_abs(input_dev, ABS_MT_PRESSURE, size);
171*4882a593Smuzhiyun 		input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, size);
172*4882a593Smuzhiyun 		input_report_abs(input_dev, ABS_MT_TRACKING_ID, id);
173*4882a593Smuzhiyun 		input_report_abs(input_dev, ABS_MT_POSITION_X, x);
174*4882a593Smuzhiyun 		input_report_abs(input_dev, ABS_MT_POSITION_Y, y);
175*4882a593Smuzhiyun 	} else {
176*4882a593Smuzhiyun 		input_report_key(input_dev, BTN_TOUCH, 1);
177*4882a593Smuzhiyun 
178*4882a593Smuzhiyun 		if ((!size) && (!id)) {
179*4882a593Smuzhiyun 			/* for virtual button */
180*4882a593Smuzhiyun 			input_report_abs(input_dev, ABS_MT_PRESSURE, 100);
181*4882a593Smuzhiyun 			input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, 100);
182*4882a593Smuzhiyun 		} else {
183*4882a593Smuzhiyun 			input_report_abs(input_dev, ABS_MT_PRESSURE, size);
184*4882a593Smuzhiyun 			input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, size);
185*4882a593Smuzhiyun 			input_report_abs(input_dev, ABS_MT_TRACKING_ID, id);
186*4882a593Smuzhiyun 		}
187*4882a593Smuzhiyun 		input_report_abs(input_dev, ABS_MT_POSITION_X, x);
188*4882a593Smuzhiyun 		input_report_abs(input_dev, ABS_MT_POSITION_Y, y);
189*4882a593Smuzhiyun 		input_mt_sync(input_dev);
190*4882a593Smuzhiyun 
191*4882a593Smuzhiyun 	}
192*4882a593Smuzhiyun }
193*4882a593Smuzhiyun 
194*4882a593Smuzhiyun /**
195*4882a593Smuzhiyun  * gt1x_touch_up -  Report touch release event.
196*4882a593Smuzhiyun  * @id: trackId
197*4882a593Smuzhiyun  * Return: none.
198*4882a593Smuzhiyun  */
gt1x_touch_up(s32 id)199*4882a593Smuzhiyun void gt1x_touch_up(s32 id)
200*4882a593Smuzhiyun {
201*4882a593Smuzhiyun 	if (gt1x_ics_slot_report) {
202*4882a593Smuzhiyun 		input_mt_slot(input_dev, id);
203*4882a593Smuzhiyun 		input_report_abs(input_dev, ABS_MT_TRACKING_ID, -1);
204*4882a593Smuzhiyun 	} else {
205*4882a593Smuzhiyun 		input_report_key(input_dev, BTN_TOUCH, 0);
206*4882a593Smuzhiyun 		input_mt_sync(input_dev);
207*4882a593Smuzhiyun 	}
208*4882a593Smuzhiyun }
209*4882a593Smuzhiyun 
210*4882a593Smuzhiyun /**
211*4882a593Smuzhiyun  * gt1x_ts_work_func - Goodix touchscreen work function.
212*4882a593Smuzhiyun  * @iwork: work struct of gt1x_workqueue.
213*4882a593Smuzhiyun  * Return: none.
214*4882a593Smuzhiyun  */
gt1x_ts_work_func(struct work_struct * work)215*4882a593Smuzhiyun static void gt1x_ts_work_func(struct work_struct *work)
216*4882a593Smuzhiyun {
217*4882a593Smuzhiyun 	u8 end_cmd = 0;
218*4882a593Smuzhiyun 	u8 finger = 0;
219*4882a593Smuzhiyun 	s32 ret = 0;
220*4882a593Smuzhiyun 	u8 point_data[11] = { 0 };
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun 	if (update_info.status) {
223*4882a593Smuzhiyun 		GTP_DEBUG("Ignore interrupts during fw update.");
224*4882a593Smuzhiyun 		return;
225*4882a593Smuzhiyun 	}
226*4882a593Smuzhiyun 
227*4882a593Smuzhiyun #if GTP_GESTURE_WAKEUP
228*4882a593Smuzhiyun 	ret = gesture_event_handler(input_dev);
229*4882a593Smuzhiyun 	if (ret >= 0) {
230*4882a593Smuzhiyun 		goto exit_work_func;
231*4882a593Smuzhiyun 	}
232*4882a593Smuzhiyun #endif
233*4882a593Smuzhiyun 
234*4882a593Smuzhiyun 	if (gt1x_halt) {
235*4882a593Smuzhiyun 		GTP_DEBUG("Ignore interrupts after suspend...");
236*4882a593Smuzhiyun 		return;
237*4882a593Smuzhiyun 	}
238*4882a593Smuzhiyun 
239*4882a593Smuzhiyun 	ret = gt1x_i2c_read(GTP_READ_COOR_ADDR, point_data, sizeof(point_data));
240*4882a593Smuzhiyun 	if (ret < 0) {
241*4882a593Smuzhiyun 		GTP_ERROR("I2C transfer error!");
242*4882a593Smuzhiyun #if !GTP_ESD_PROTECT
243*4882a593Smuzhiyun 		gt1x_power_reset();
244*4882a593Smuzhiyun #endif
245*4882a593Smuzhiyun 		goto exit_work_func;
246*4882a593Smuzhiyun 	}
247*4882a593Smuzhiyun 
248*4882a593Smuzhiyun 	finger = point_data[0];
249*4882a593Smuzhiyun 	if (finger == 0x00) {
250*4882a593Smuzhiyun 		gt1x_request_event_handler();
251*4882a593Smuzhiyun 	}
252*4882a593Smuzhiyun 
253*4882a593Smuzhiyun 	if ((finger & 0x80) == 0) {
254*4882a593Smuzhiyun #if HOTKNOT_BLOCK_RW
255*4882a593Smuzhiyun 		if (!hotknot_paired_flag)
256*4882a593Smuzhiyun #endif
257*4882a593Smuzhiyun 		{
258*4882a593Smuzhiyun 			/*GTP_ERROR("buffer not ready:0x%02x", finger);*/
259*4882a593Smuzhiyun 			goto exit_eint;
260*4882a593Smuzhiyun 		}
261*4882a593Smuzhiyun 	}
262*4882a593Smuzhiyun #if HOTKNOT_BLOCK_RW
263*4882a593Smuzhiyun 	ret = hotknot_event_handler(point_data);
264*4882a593Smuzhiyun 	if (!ret) {
265*4882a593Smuzhiyun 		goto exit_work_func;
266*4882a593Smuzhiyun 	}
267*4882a593Smuzhiyun #endif
268*4882a593Smuzhiyun 
269*4882a593Smuzhiyun #if GTP_PROXIMITY
270*4882a593Smuzhiyun 	ret = gt1x_prox_event_handler(point_data);
271*4882a593Smuzhiyun 	if (ret > 0) {
272*4882a593Smuzhiyun 		goto exit_work_func;
273*4882a593Smuzhiyun 	}
274*4882a593Smuzhiyun #endif
275*4882a593Smuzhiyun 
276*4882a593Smuzhiyun #if GTP_WITH_STYLUS
277*4882a593Smuzhiyun 	ret = gt1x_touch_event_handler(point_data, input_dev, pen_dev);
278*4882a593Smuzhiyun #else
279*4882a593Smuzhiyun 	ret = gt1x_touch_event_handler(point_data, input_dev, NULL);
280*4882a593Smuzhiyun #endif
281*4882a593Smuzhiyun 
282*4882a593Smuzhiyun exit_work_func:
283*4882a593Smuzhiyun 	if (!gt1x_rawdiff_mode && (ret >= 0 || ret == ERROR_VALUE)) {
284*4882a593Smuzhiyun 		ret = gt1x_i2c_write(GTP_READ_COOR_ADDR, &end_cmd, 1);
285*4882a593Smuzhiyun 		if (ret < 0) {
286*4882a593Smuzhiyun 			GTP_ERROR("I2C write end_cmd  error!");
287*4882a593Smuzhiyun 		}
288*4882a593Smuzhiyun 	}
289*4882a593Smuzhiyun exit_eint:
290*4882a593Smuzhiyun 	gt1x_irq_enable();
291*4882a593Smuzhiyun 
292*4882a593Smuzhiyun }
293*4882a593Smuzhiyun 
294*4882a593Smuzhiyun /*
295*4882a593Smuzhiyun  * Devices Tree support,
296*4882a593Smuzhiyun  */
297*4882a593Smuzhiyun #ifdef GTP_CONFIG_OF
298*4882a593Smuzhiyun 
299*4882a593Smuzhiyun static struct regulator *vdd_ana;
300*4882a593Smuzhiyun /**
301*4882a593Smuzhiyun  * gt1x_parse_dt - parse platform infomation form devices tree.
302*4882a593Smuzhiyun  */
gt1x_parse_dt(struct device * dev)303*4882a593Smuzhiyun static int gt1x_parse_dt(struct device *dev)
304*4882a593Smuzhiyun {
305*4882a593Smuzhiyun 	struct device_node *np;
306*4882a593Smuzhiyun 	const char *tp_type;
307*4882a593Smuzhiyun #ifdef CONFIG_PM
308*4882a593Smuzhiyun 	struct device_node *root;
309*4882a593Smuzhiyun 	const char *machine_compatible;
310*4882a593Smuzhiyun #endif
311*4882a593Smuzhiyun 
312*4882a593Smuzhiyun 	if (!dev)
313*4882a593Smuzhiyun 		return -ENODEV;
314*4882a593Smuzhiyun 
315*4882a593Smuzhiyun 	np = dev->of_node;
316*4882a593Smuzhiyun 
317*4882a593Smuzhiyun 	if (!of_property_read_string(np, "goodix,ic_type", &tp_type)) {
318*4882a593Smuzhiyun 		GTP_INFO("GTP ic_type: %s", tp_type);
319*4882a593Smuzhiyun 
320*4882a593Smuzhiyun 		if (strstr(tp_type, "gt5688"))
321*4882a593Smuzhiyun 			gt1x_gt5688 = true;
322*4882a593Smuzhiyun 	}
323*4882a593Smuzhiyun 
324*4882a593Smuzhiyun 	gt1x_int_gpio = of_get_named_gpio(np, "goodix,irq-gpio", 0);
325*4882a593Smuzhiyun 	gt1x_rst_gpio = of_get_named_gpio(np, "goodix,rst-gpio", 0);
326*4882a593Smuzhiyun 
327*4882a593Smuzhiyun 	if (!gpio_is_valid(gt1x_int_gpio) && !gpio_is_valid(gt1x_rst_gpio)) {
328*4882a593Smuzhiyun 		GTP_ERROR("Invalid GPIO, irq-gpio:%d, rst-gpio:%d",
329*4882a593Smuzhiyun 				gt1x_int_gpio, gt1x_rst_gpio);
330*4882a593Smuzhiyun 		return -EINVAL;
331*4882a593Smuzhiyun 	}
332*4882a593Smuzhiyun 
333*4882a593Smuzhiyun 	if (!gpio_is_valid(gt1x_int_gpio)) {
334*4882a593Smuzhiyun 		GTP_ERROR("Invalid GPIO, irq-gpio:%d",
335*4882a593Smuzhiyun 				gt1x_int_gpio);
336*4882a593Smuzhiyun 		return -EINVAL;
337*4882a593Smuzhiyun 	}
338*4882a593Smuzhiyun 
339*4882a593Smuzhiyun 	vdd_ana = devm_regulator_get_optional(dev, "vdd_ana");
340*4882a593Smuzhiyun 	if (PTR_ERR(vdd_ana) == -ENODEV) {
341*4882a593Smuzhiyun 		GTP_ERROR("vdd_ana not specified, fallback to power-supply");
342*4882a593Smuzhiyun 		vdd_ana = devm_regulator_get_optional(dev, "power");
343*4882a593Smuzhiyun 		if (PTR_ERR(vdd_ana) == -ENODEV) {
344*4882a593Smuzhiyun 			GTP_ERROR("power not specified, ignore power ctrl");
345*4882a593Smuzhiyun 			vdd_ana = NULL;
346*4882a593Smuzhiyun 		} else {
347*4882a593Smuzhiyun 			power_invert = of_property_read_bool(np, "power-invert");
348*4882a593Smuzhiyun 			GTP_INFO("Power Invert,%s ", power_invert ? "yes" : "no");
349*4882a593Smuzhiyun 		}
350*4882a593Smuzhiyun 	}
351*4882a593Smuzhiyun 	if (IS_ERR(vdd_ana)) {
352*4882a593Smuzhiyun 		GTP_ERROR("regulator get of vdd_ana/power-supply failed");
353*4882a593Smuzhiyun 		return PTR_ERR(vdd_ana);
354*4882a593Smuzhiyun 	}
355*4882a593Smuzhiyun 
356*4882a593Smuzhiyun 	gt1x_ics_slot_report = of_property_read_bool(dev->of_node, "gtp_ics_slot_report");
357*4882a593Smuzhiyun #ifdef CONFIG_PM
358*4882a593Smuzhiyun 	root = of_find_node_by_path("/");
359*4882a593Smuzhiyun 	if (root) {
360*4882a593Smuzhiyun 		machine_compatible = of_get_property(root, "compatible", NULL);
361*4882a593Smuzhiyun 		of_node_put(root);
362*4882a593Smuzhiyun 		if (strstr(machine_compatible, "linux"))
363*4882a593Smuzhiyun 			dev->driver->pm = &gt1x_ts_pm_ops;
364*4882a593Smuzhiyun 	}
365*4882a593Smuzhiyun #endif
366*4882a593Smuzhiyun 
367*4882a593Smuzhiyun 	return 0;
368*4882a593Smuzhiyun }
369*4882a593Smuzhiyun 
370*4882a593Smuzhiyun /**
371*4882a593Smuzhiyun  * gt1x_power_switch - power switch .
372*4882a593Smuzhiyun  * @on: 1-switch on, 0-switch off.
373*4882a593Smuzhiyun  * return: 0-succeed, -1-faileds
374*4882a593Smuzhiyun  */
gt1x_power_switch(int on)375*4882a593Smuzhiyun int gt1x_power_switch(int on)
376*4882a593Smuzhiyun {
377*4882a593Smuzhiyun 	int ret = 0;
378*4882a593Smuzhiyun 	struct i2c_client *client = gt1x_i2c_client;
379*4882a593Smuzhiyun 
380*4882a593Smuzhiyun 	if (!client || !vdd_ana)
381*4882a593Smuzhiyun 		return -1;
382*4882a593Smuzhiyun 
383*4882a593Smuzhiyun 	if (on) {
384*4882a593Smuzhiyun 		GTP_DEBUG("GTP power on.");
385*4882a593Smuzhiyun 		if (power_invert) {
386*4882a593Smuzhiyun 			if (regulator_is_enabled(vdd_ana) > 0)
387*4882a593Smuzhiyun 				ret = regulator_disable(vdd_ana);
388*4882a593Smuzhiyun 		} else {
389*4882a593Smuzhiyun 			ret = regulator_enable(vdd_ana);
390*4882a593Smuzhiyun 		}
391*4882a593Smuzhiyun 	} else {
392*4882a593Smuzhiyun 		GTP_DEBUG("GTP power off.");
393*4882a593Smuzhiyun 		if (power_invert) {
394*4882a593Smuzhiyun 			if (!regulator_is_enabled(vdd_ana))
395*4882a593Smuzhiyun 				ret = regulator_enable(vdd_ana);
396*4882a593Smuzhiyun 		} else {
397*4882a593Smuzhiyun 			ret = regulator_disable(vdd_ana);
398*4882a593Smuzhiyun 		}
399*4882a593Smuzhiyun 	}
400*4882a593Smuzhiyun 	return ret;
401*4882a593Smuzhiyun }
402*4882a593Smuzhiyun #endif
403*4882a593Smuzhiyun 
gt1x_remove_gpio_and_power(void)404*4882a593Smuzhiyun static void gt1x_remove_gpio_and_power(void)
405*4882a593Smuzhiyun {
406*4882a593Smuzhiyun 	if (gpio_is_valid(gt1x_int_gpio))
407*4882a593Smuzhiyun 		gpio_free(gt1x_int_gpio);
408*4882a593Smuzhiyun 
409*4882a593Smuzhiyun 	if (gpio_is_valid(gt1x_rst_gpio))
410*4882a593Smuzhiyun 		gpio_free(gt1x_rst_gpio);
411*4882a593Smuzhiyun 
412*4882a593Smuzhiyun 	if (gt1x_i2c_client && gt1x_i2c_client->irq)
413*4882a593Smuzhiyun 		free_irq(gt1x_i2c_client->irq, gt1x_i2c_client);
414*4882a593Smuzhiyun }
415*4882a593Smuzhiyun 
416*4882a593Smuzhiyun 
417*4882a593Smuzhiyun /**
418*4882a593Smuzhiyun  * gt1x_request_io_port - Request gpio(INT & RST) ports.
419*4882a593Smuzhiyun  */
gt1x_request_io_port(void)420*4882a593Smuzhiyun static s32 gt1x_request_io_port(void)
421*4882a593Smuzhiyun {
422*4882a593Smuzhiyun 	s32 ret = 0;
423*4882a593Smuzhiyun 
424*4882a593Smuzhiyun 	GTP_DEBUG_FUNC();
425*4882a593Smuzhiyun 	ret = gpio_request(GTP_INT_PORT, "GTP_INT_IRQ");
426*4882a593Smuzhiyun 	if (ret < 0) {
427*4882a593Smuzhiyun 		GTP_ERROR("Failed to request GPIO:%d, ERRNO:%d", (s32) GTP_INT_PORT, ret);
428*4882a593Smuzhiyun 		return ret;
429*4882a593Smuzhiyun 	}
430*4882a593Smuzhiyun 
431*4882a593Smuzhiyun 	GTP_GPIO_AS_INT(GTP_INT_PORT);
432*4882a593Smuzhiyun 	gt1x_i2c_client->irq = GTP_INT_IRQ;
433*4882a593Smuzhiyun 
434*4882a593Smuzhiyun 	if (gpio_is_valid(gt1x_rst_gpio)) {
435*4882a593Smuzhiyun 		ret = gpio_request(GTP_RST_PORT, "GTP_RST_PORT");
436*4882a593Smuzhiyun 		if (ret < 0) {
437*4882a593Smuzhiyun 			GTP_ERROR("Failed to request GPIO:%d, ERRNO:%d", (s32) GTP_RST_PORT, ret);
438*4882a593Smuzhiyun 			gpio_free(GTP_INT_PORT);
439*4882a593Smuzhiyun 			return ret;
440*4882a593Smuzhiyun 		}
441*4882a593Smuzhiyun 
442*4882a593Smuzhiyun 	GTP_GPIO_AS_INPUT(GTP_RST_PORT);
443*4882a593Smuzhiyun 	}
444*4882a593Smuzhiyun 
445*4882a593Smuzhiyun 	return 0;
446*4882a593Smuzhiyun }
447*4882a593Smuzhiyun 
448*4882a593Smuzhiyun /**
449*4882a593Smuzhiyun  * gt1x_request_irq - Request interrupt.
450*4882a593Smuzhiyun  * Return
451*4882a593Smuzhiyun  *      0: succeed, -1: failed.
452*4882a593Smuzhiyun  */
gt1x_request_irq(void)453*4882a593Smuzhiyun static s32 gt1x_request_irq(void)
454*4882a593Smuzhiyun {
455*4882a593Smuzhiyun 	s32 ret = -1;
456*4882a593Smuzhiyun 	const u8 irq_table[] = GTP_IRQ_TAB;
457*4882a593Smuzhiyun 
458*4882a593Smuzhiyun 	GTP_DEBUG_FUNC();
459*4882a593Smuzhiyun 	GTP_DEBUG("INT trigger type:%x", gt1x_int_type);
460*4882a593Smuzhiyun 
461*4882a593Smuzhiyun 	ret = request_irq(gt1x_i2c_client->irq, gt1x_ts_irq_handler, irq_table[gt1x_int_type], gt1x_i2c_client->name, gt1x_i2c_client);
462*4882a593Smuzhiyun 	if (ret) {
463*4882a593Smuzhiyun 		GTP_ERROR("Request IRQ failed!ERRNO:%d.", ret);
464*4882a593Smuzhiyun 		GTP_GPIO_AS_INPUT(GTP_INT_PORT);
465*4882a593Smuzhiyun 		gpio_free(GTP_INT_PORT);
466*4882a593Smuzhiyun 
467*4882a593Smuzhiyun 		return -1;
468*4882a593Smuzhiyun 	} else {
469*4882a593Smuzhiyun 		gt1x_irq_disable();
470*4882a593Smuzhiyun 		return 0;
471*4882a593Smuzhiyun 	}
472*4882a593Smuzhiyun }
473*4882a593Smuzhiyun 
474*4882a593Smuzhiyun /**
475*4882a593Smuzhiyun  * gt1x_request_input_dev -  Request input device Function.
476*4882a593Smuzhiyun  * Return
477*4882a593Smuzhiyun  *      0: succeed, -1: failed.
478*4882a593Smuzhiyun  */
gt1x_request_input_dev(void)479*4882a593Smuzhiyun static s8 gt1x_request_input_dev(void)
480*4882a593Smuzhiyun {
481*4882a593Smuzhiyun 	s8 ret = -1;
482*4882a593Smuzhiyun #if GTP_HAVE_TOUCH_KEY
483*4882a593Smuzhiyun 	u8 index = 0;
484*4882a593Smuzhiyun #endif
485*4882a593Smuzhiyun 
486*4882a593Smuzhiyun 	GTP_DEBUG_FUNC();
487*4882a593Smuzhiyun 
488*4882a593Smuzhiyun 	input_dev = input_allocate_device();
489*4882a593Smuzhiyun 	if (input_dev == NULL) {
490*4882a593Smuzhiyun 		GTP_ERROR("Failed to allocate input device.");
491*4882a593Smuzhiyun 		return -ENOMEM;
492*4882a593Smuzhiyun 	}
493*4882a593Smuzhiyun 
494*4882a593Smuzhiyun 	input_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
495*4882a593Smuzhiyun 	if (gt1x_ics_slot_report) {
496*4882a593Smuzhiyun #if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 7, 0))
497*4882a593Smuzhiyun 		input_mt_init_slots(input_dev, 16, INPUT_MT_DIRECT);
498*4882a593Smuzhiyun #else
499*4882a593Smuzhiyun 		input_mt_init_slots(input_dev, 16);
500*4882a593Smuzhiyun #endif
501*4882a593Smuzhiyun 	} else {
502*4882a593Smuzhiyun 		input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
503*4882a593Smuzhiyun 	}
504*4882a593Smuzhiyun 	set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
505*4882a593Smuzhiyun 
506*4882a593Smuzhiyun #if GTP_HAVE_TOUCH_KEY
507*4882a593Smuzhiyun 	for (index = 0; index < GTP_MAX_KEY_NUM; index++) {
508*4882a593Smuzhiyun 		input_set_capability(input_dev, EV_KEY, gt1x_touch_key_array[index]);
509*4882a593Smuzhiyun 	}
510*4882a593Smuzhiyun #endif
511*4882a593Smuzhiyun 
512*4882a593Smuzhiyun #if GTP_GESTURE_WAKEUP
513*4882a593Smuzhiyun 	input_set_capability(input_dev, EV_KEY, KEY_GES_REGULAR);
514*4882a593Smuzhiyun 	input_set_capability(input_dev, EV_KEY, KEY_GES_CUSTOM);
515*4882a593Smuzhiyun #endif
516*4882a593Smuzhiyun 
517*4882a593Smuzhiyun #if GTP_CHANGE_X2Y
518*4882a593Smuzhiyun 	input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, gt1x_abs_y_max, 0, 0);
519*4882a593Smuzhiyun 	input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, gt1x_abs_x_max, 0, 0);
520*4882a593Smuzhiyun #else
521*4882a593Smuzhiyun 	input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, gt1x_abs_x_max, 0, 0);
522*4882a593Smuzhiyun 	input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, gt1x_abs_y_max, 0, 0);
523*4882a593Smuzhiyun #endif
524*4882a593Smuzhiyun 	input_set_abs_params(input_dev, ABS_MT_PRESSURE, 0, 255, 0, 0);
525*4882a593Smuzhiyun 	input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
526*4882a593Smuzhiyun 	input_set_abs_params(input_dev, ABS_MT_TRACKING_ID, 0, 255, 0, 0);
527*4882a593Smuzhiyun 
528*4882a593Smuzhiyun 	input_set_abs_params(input_dev, ABS_X, 0, 255, 0, 0);
529*4882a593Smuzhiyun 	input_set_abs_params(input_dev, ABS_Y, 0, 255, 0, 0);
530*4882a593Smuzhiyun 
531*4882a593Smuzhiyun 	input_dev->name = gt1x_ts_name;
532*4882a593Smuzhiyun 	input_dev->phys = input_dev_phys;
533*4882a593Smuzhiyun 	input_dev->id.bustype = BUS_I2C;
534*4882a593Smuzhiyun 	input_dev->id.vendor = 0xDEAD;
535*4882a593Smuzhiyun 	input_dev->id.product = 0xBEEF;
536*4882a593Smuzhiyun 	input_dev->id.version = 10427;
537*4882a593Smuzhiyun 
538*4882a593Smuzhiyun 	ret = input_register_device(input_dev);
539*4882a593Smuzhiyun 	if (ret) {
540*4882a593Smuzhiyun 		GTP_ERROR("Register %s input device failed", input_dev->name);
541*4882a593Smuzhiyun 		return -ENODEV;
542*4882a593Smuzhiyun 	}
543*4882a593Smuzhiyun 
544*4882a593Smuzhiyun 	return 0;
545*4882a593Smuzhiyun }
546*4882a593Smuzhiyun 
547*4882a593Smuzhiyun /**
548*4882a593Smuzhiyun  * gt1x_ts_probe -   I2c probe.
549*4882a593Smuzhiyun  * @client: i2c device struct.
550*4882a593Smuzhiyun  * @id: device id.
551*4882a593Smuzhiyun  * Return  0: succeed, -1: failed.
552*4882a593Smuzhiyun  */
gt1x_ts_probe(struct i2c_client * client,const struct i2c_device_id * id)553*4882a593Smuzhiyun static int gt1x_ts_probe(struct i2c_client *client, const struct i2c_device_id *id)
554*4882a593Smuzhiyun {
555*4882a593Smuzhiyun 	s32 ret = -1;
556*4882a593Smuzhiyun #if GTP_AUTO_UPDATE
557*4882a593Smuzhiyun 	struct task_struct *thread = NULL;
558*4882a593Smuzhiyun #endif
559*4882a593Smuzhiyun 	/*do NOT remove these logs*/
560*4882a593Smuzhiyun 	GTP_INFO("GTP Driver Version: %s", GTP_DRIVER_VERSION);
561*4882a593Smuzhiyun 	GTP_INFO("GTP I2C Address: 0x%02x", client->addr);
562*4882a593Smuzhiyun 
563*4882a593Smuzhiyun 	gt1x_i2c_client = client;
564*4882a593Smuzhiyun 	spin_lock_init(&irq_lock);
565*4882a593Smuzhiyun 
566*4882a593Smuzhiyun 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
567*4882a593Smuzhiyun 		GTP_ERROR("I2C check functionality failed.");
568*4882a593Smuzhiyun 		return -ENODEV;
569*4882a593Smuzhiyun 	}
570*4882a593Smuzhiyun 
571*4882a593Smuzhiyun #ifdef GTP_CONFIG_OF	/* device tree support */
572*4882a593Smuzhiyun 	if (client->dev.of_node) {
573*4882a593Smuzhiyun 		ret = gt1x_parse_dt(&client->dev);
574*4882a593Smuzhiyun 		if (ret)
575*4882a593Smuzhiyun 			return ret;
576*4882a593Smuzhiyun 	}
577*4882a593Smuzhiyun #endif
578*4882a593Smuzhiyun 
579*4882a593Smuzhiyun 	ret = gt1x_request_io_port();
580*4882a593Smuzhiyun 	if (ret < 0) {
581*4882a593Smuzhiyun 		GTP_ERROR("GTP request IO port failed.");
582*4882a593Smuzhiyun 		return ret;
583*4882a593Smuzhiyun 	}
584*4882a593Smuzhiyun 
585*4882a593Smuzhiyun 	ret = gt1x_init();
586*4882a593Smuzhiyun 	if (ret != 0) {
587*4882a593Smuzhiyun 		GTP_ERROR("GTP init failed!!!");
588*4882a593Smuzhiyun 		return ret;
589*4882a593Smuzhiyun 	}
590*4882a593Smuzhiyun 
591*4882a593Smuzhiyun 	gt1x_wq = create_singlethread_workqueue("gt1x_wq");
592*4882a593Smuzhiyun 	if (!gt1x_wq) {
593*4882a593Smuzhiyun 		GTP_ERROR("Creat workqueue failed.");
594*4882a593Smuzhiyun 		return -ENOMEM;
595*4882a593Smuzhiyun 	}
596*4882a593Smuzhiyun 
597*4882a593Smuzhiyun 	INIT_WORK(&gt1x_work, gt1x_ts_work_func);
598*4882a593Smuzhiyun 
599*4882a593Smuzhiyun 	ret = gt1x_request_input_dev();
600*4882a593Smuzhiyun 	if (ret < 0) {
601*4882a593Smuzhiyun 		GTP_ERROR("GTP request input dev failed");
602*4882a593Smuzhiyun 	}
603*4882a593Smuzhiyun 
604*4882a593Smuzhiyun 	ret = gt1x_request_irq();
605*4882a593Smuzhiyun 	if (ret < 0) {
606*4882a593Smuzhiyun 		GTP_DEBUG("GTP works in polling mode.");
607*4882a593Smuzhiyun 	} else {
608*4882a593Smuzhiyun 		GTP_DEBUG("GTP works in interrupt mode.");
609*4882a593Smuzhiyun 	}
610*4882a593Smuzhiyun 
611*4882a593Smuzhiyun #if GTP_GESTURE_WAKEUP
612*4882a593Smuzhiyun 	enable_irq_wake(client->irq);
613*4882a593Smuzhiyun #endif
614*4882a593Smuzhiyun 
615*4882a593Smuzhiyun 	gt1x_irq_enable();
616*4882a593Smuzhiyun 
617*4882a593Smuzhiyun #if GTP_ESD_PROTECT
618*4882a593Smuzhiyun 	/*must before auto update*/
619*4882a593Smuzhiyun 	gt1x_init_esd_protect();
620*4882a593Smuzhiyun 	gt1x_esd_switch(SWITCH_ON);
621*4882a593Smuzhiyun #endif
622*4882a593Smuzhiyun 
623*4882a593Smuzhiyun #if GTP_AUTO_UPDATE
624*4882a593Smuzhiyun 	thread = kthread_run(gt1x_auto_update_proc, (void *)NULL, "gt1x_auto_update");
625*4882a593Smuzhiyun 	if (IS_ERR(thread)) {
626*4882a593Smuzhiyun 		ret = PTR_ERR(thread);
627*4882a593Smuzhiyun 		GTP_ERROR("Failed to create auto-update thread: %d.", ret);
628*4882a593Smuzhiyun 	}
629*4882a593Smuzhiyun #endif
630*4882a593Smuzhiyun 	gt1x_register_powermanger();
631*4882a593Smuzhiyun 	return 0;
632*4882a593Smuzhiyun }
633*4882a593Smuzhiyun 
634*4882a593Smuzhiyun /**
635*4882a593Smuzhiyun  * gt1x_ts_remove -  Goodix touchscreen driver release function.
636*4882a593Smuzhiyun  * @client: i2c device struct.
637*4882a593Smuzhiyun  * Return  0: succeed, -1: failed.
638*4882a593Smuzhiyun  */
gt1x_ts_remove(struct i2c_client * client)639*4882a593Smuzhiyun static int gt1x_ts_remove(struct i2c_client *client)
640*4882a593Smuzhiyun {
641*4882a593Smuzhiyun 	GTP_DEBUG_FUNC();
642*4882a593Smuzhiyun 	GTP_DEBUG("GTP driver removing...");
643*4882a593Smuzhiyun 	gt1x_unregister_powermanger();
644*4882a593Smuzhiyun 
645*4882a593Smuzhiyun #if GTP_GESTURE_WAKEUP
646*4882a593Smuzhiyun 	disable_irq_wake(client->irq);
647*4882a593Smuzhiyun #endif
648*4882a593Smuzhiyun 	gt1x_deinit();
649*4882a593Smuzhiyun 	input_unregister_device(input_dev);
650*4882a593Smuzhiyun 	gt1x_remove_gpio_and_power();
651*4882a593Smuzhiyun 	if (gt1x_wq) {
652*4882a593Smuzhiyun 		destroy_workqueue(gt1x_wq);
653*4882a593Smuzhiyun 	}
654*4882a593Smuzhiyun 
655*4882a593Smuzhiyun 	return 0;
656*4882a593Smuzhiyun }
657*4882a593Smuzhiyun 
658*4882a593Smuzhiyun #if defined(CONFIG_FB)
659*4882a593Smuzhiyun /* frame buffer notifier block control the suspend/resume procedure */
660*4882a593Smuzhiyun static struct notifier_block gt1x_fb_notifier;
661*4882a593Smuzhiyun static int tp_status;
662*4882a593Smuzhiyun 
gtp_fb_notifier_callback(struct notifier_block * noti,unsigned long event,void * data)663*4882a593Smuzhiyun static int gtp_fb_notifier_callback(struct notifier_block *noti, unsigned long event, void *data)
664*4882a593Smuzhiyun {
665*4882a593Smuzhiyun 	struct fb_event *ev_data = data;
666*4882a593Smuzhiyun 	int *blank;
667*4882a593Smuzhiyun 
668*4882a593Smuzhiyun #if GTP_INCELL_PANEL
669*4882a593Smuzhiyun #ifndef FB_EARLY_EVENT_BLANK
670*4882a593Smuzhiyun #error Need add FB_EARLY_EVENT_BLANK to fbmem.c
671*4882a593Smuzhiyun #endif
672*4882a593Smuzhiyun 
673*4882a593Smuzhiyun 	if (ev_data && ev_data->data && event == FB_EARLY_EVENT_BLANK
674*4882a593Smuzhiyun 	    && tp_status != FB_BLANK_UNBLANK) {
675*4882a593Smuzhiyun 		blank = ev_data->data;
676*4882a593Smuzhiyun 		if (*blank == FB_BLANK_UNBLANK) {
677*4882a593Smuzhiyun 			tp_status = *blank;
678*4882a593Smuzhiyun 			GTP_DEBUG("Resume by fb notifier.");
679*4882a593Smuzhiyun 			gt1x_resume();
680*4882a593Smuzhiyun 		}
681*4882a593Smuzhiyun 	}
682*4882a593Smuzhiyun #else
683*4882a593Smuzhiyun 	if (ev_data && ev_data->data && event == FB_EVENT_BLANK
684*4882a593Smuzhiyun 	    && tp_status != FB_BLANK_UNBLANK) {
685*4882a593Smuzhiyun 		blank = ev_data->data;
686*4882a593Smuzhiyun 		if (*blank == FB_BLANK_UNBLANK) {
687*4882a593Smuzhiyun 			tp_status = *blank;
688*4882a593Smuzhiyun 			GTP_DEBUG("Resume by fb notifier.");
689*4882a593Smuzhiyun 			gt1x_resume();
690*4882a593Smuzhiyun 		}
691*4882a593Smuzhiyun 	}
692*4882a593Smuzhiyun #endif
693*4882a593Smuzhiyun 
694*4882a593Smuzhiyun 	if (ev_data && ev_data->data && event == FB_EVENT_BLANK
695*4882a593Smuzhiyun 	    && tp_status == FB_BLANK_UNBLANK) {
696*4882a593Smuzhiyun 		blank = ev_data->data;
697*4882a593Smuzhiyun 		if (*blank == FB_BLANK_POWERDOWN) {
698*4882a593Smuzhiyun 			tp_status = *blank;
699*4882a593Smuzhiyun 			GTP_DEBUG("Suspend by fb notifier.");
700*4882a593Smuzhiyun 			gt1x_suspend();
701*4882a593Smuzhiyun 		}
702*4882a593Smuzhiyun 	}
703*4882a593Smuzhiyun 
704*4882a593Smuzhiyun 	return 0;
705*4882a593Smuzhiyun }
706*4882a593Smuzhiyun #elif defined(CONFIG_HAS_EARLYSUSPEND)
707*4882a593Smuzhiyun /* earlysuspend module the suspend/resume procedure */
gt1x_ts_early_suspend(struct early_suspend * h)708*4882a593Smuzhiyun static void gt1x_ts_early_suspend(struct early_suspend *h)
709*4882a593Smuzhiyun {
710*4882a593Smuzhiyun 	gt1x_suspend();
711*4882a593Smuzhiyun }
712*4882a593Smuzhiyun 
gt1x_ts_late_resume(struct early_suspend * h)713*4882a593Smuzhiyun static void gt1x_ts_late_resume(struct early_suspend *h)
714*4882a593Smuzhiyun {
715*4882a593Smuzhiyun 	gt1x_resume();
716*4882a593Smuzhiyun }
717*4882a593Smuzhiyun 
718*4882a593Smuzhiyun static struct early_suspend gt1x_early_suspend = {
719*4882a593Smuzhiyun 	.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1,
720*4882a593Smuzhiyun 	.suspend = gt1x_ts_early_suspend,
721*4882a593Smuzhiyun 	.resume = gt1x_ts_late_resume,
722*4882a593Smuzhiyun };
723*4882a593Smuzhiyun #endif
724*4882a593Smuzhiyun 
725*4882a593Smuzhiyun #ifdef CONFIG_PM
726*4882a593Smuzhiyun /**
727*4882a593Smuzhiyun  * gt1x_ts_suspend - i2c suspend callback function.
728*4882a593Smuzhiyun  * @dev: i2c device.
729*4882a593Smuzhiyun  * Return  0: succeed, -1: failed.
730*4882a593Smuzhiyun  */
gt1x_pm_suspend(struct device * dev)731*4882a593Smuzhiyun static int gt1x_pm_suspend(struct device *dev)
732*4882a593Smuzhiyun {
733*4882a593Smuzhiyun     return gt1x_suspend();
734*4882a593Smuzhiyun }
735*4882a593Smuzhiyun 
736*4882a593Smuzhiyun /**
737*4882a593Smuzhiyun  * gt1x_ts_resume - i2c resume callback function.
738*4882a593Smuzhiyun  * @dev: i2c device.
739*4882a593Smuzhiyun  * Return  0: succeed, -1: failed.
740*4882a593Smuzhiyun  */
gt1x_pm_resume(struct device * dev)741*4882a593Smuzhiyun static int gt1x_pm_resume(struct device *dev)
742*4882a593Smuzhiyun {
743*4882a593Smuzhiyun 	return gt1x_resume();
744*4882a593Smuzhiyun }
745*4882a593Smuzhiyun 
746*4882a593Smuzhiyun /* bus control the suspend/resume procedure */
747*4882a593Smuzhiyun static const struct dev_pm_ops gt1x_ts_pm_ops = {
748*4882a593Smuzhiyun 	.suspend = gt1x_pm_suspend,
749*4882a593Smuzhiyun 	.resume = gt1x_pm_resume,
750*4882a593Smuzhiyun };
751*4882a593Smuzhiyun #endif
752*4882a593Smuzhiyun 
gt1x_register_powermanger(void)753*4882a593Smuzhiyun static int gt1x_register_powermanger(void)
754*4882a593Smuzhiyun {
755*4882a593Smuzhiyun #if   defined(CONFIG_FB)
756*4882a593Smuzhiyun 	tp_status = FB_BLANK_UNBLANK;
757*4882a593Smuzhiyun 	gt1x_fb_notifier.notifier_call = gtp_fb_notifier_callback;
758*4882a593Smuzhiyun 	fb_register_client(&gt1x_fb_notifier);
759*4882a593Smuzhiyun 
760*4882a593Smuzhiyun #elif defined(CONFIG_HAS_EARLYSUSPEND)
761*4882a593Smuzhiyun 	register_early_suspend(&gt1x_early_suspend);
762*4882a593Smuzhiyun #endif
763*4882a593Smuzhiyun 	return 0;
764*4882a593Smuzhiyun }
765*4882a593Smuzhiyun 
gt1x_unregister_powermanger(void)766*4882a593Smuzhiyun static int gt1x_unregister_powermanger(void)
767*4882a593Smuzhiyun {
768*4882a593Smuzhiyun #if   defined(CONFIG_FB)
769*4882a593Smuzhiyun 	fb_unregister_client(&gt1x_fb_notifier);
770*4882a593Smuzhiyun 
771*4882a593Smuzhiyun #elif defined(CONFIG_HAS_EARLYSUSPEND)
772*4882a593Smuzhiyun 	unregister_early_suspend(&gt1x_early_suspend);
773*4882a593Smuzhiyun #endif
774*4882a593Smuzhiyun 	return 0;
775*4882a593Smuzhiyun }
776*4882a593Smuzhiyun 
777*4882a593Smuzhiyun #ifdef GTP_CONFIG_OF
778*4882a593Smuzhiyun static const struct of_device_id gt1x_match_table[] = {
779*4882a593Smuzhiyun 		{.compatible = "goodix,gt1x",},
780*4882a593Smuzhiyun 		{ },
781*4882a593Smuzhiyun };
782*4882a593Smuzhiyun #endif
783*4882a593Smuzhiyun 
784*4882a593Smuzhiyun static const struct i2c_device_id gt1x_ts_id[] = {
785*4882a593Smuzhiyun 	{GTP_I2C_NAME, 0},
786*4882a593Smuzhiyun 	{}
787*4882a593Smuzhiyun };
788*4882a593Smuzhiyun 
789*4882a593Smuzhiyun static struct i2c_driver gt1x_ts_driver = {
790*4882a593Smuzhiyun 	.probe = gt1x_ts_probe,
791*4882a593Smuzhiyun 	.remove = gt1x_ts_remove,
792*4882a593Smuzhiyun 	.id_table = gt1x_ts_id,
793*4882a593Smuzhiyun 	.driver = {
794*4882a593Smuzhiyun 		   .name = GTP_I2C_NAME,
795*4882a593Smuzhiyun #ifdef GTP_CONFIG_OF
796*4882a593Smuzhiyun 		   .of_match_table = gt1x_match_table,
797*4882a593Smuzhiyun #endif
798*4882a593Smuzhiyun #if !defined(CONFIG_FB) && defined(CONFIG_PM)
799*4882a593Smuzhiyun 		   .pm = &gt1x_ts_pm_ops,
800*4882a593Smuzhiyun #endif
801*4882a593Smuzhiyun 		   .probe_type = PROBE_PREFER_ASYNCHRONOUS,
802*4882a593Smuzhiyun 		   },
803*4882a593Smuzhiyun };
804*4882a593Smuzhiyun 
805*4882a593Smuzhiyun /**
806*4882a593Smuzhiyun  * gt1x_ts_init - Driver Install function.
807*4882a593Smuzhiyun  * Return   0---succeed.
808*4882a593Smuzhiyun  */
gt1x_ts_init(void)809*4882a593Smuzhiyun static int __init gt1x_ts_init(void)
810*4882a593Smuzhiyun {
811*4882a593Smuzhiyun 	GTP_DEBUG_FUNC();
812*4882a593Smuzhiyun 	GTP_DEBUG("GTP driver installing...");
813*4882a593Smuzhiyun 
814*4882a593Smuzhiyun 	return i2c_add_driver(&gt1x_ts_driver);
815*4882a593Smuzhiyun }
816*4882a593Smuzhiyun 
817*4882a593Smuzhiyun /**
818*4882a593Smuzhiyun  * gt1x_ts_exit - Driver uninstall function.
819*4882a593Smuzhiyun  * Return   0---succeed.
820*4882a593Smuzhiyun  */
gt1x_ts_exit(void)821*4882a593Smuzhiyun static void __exit gt1x_ts_exit(void)
822*4882a593Smuzhiyun {
823*4882a593Smuzhiyun 	GTP_DEBUG_FUNC();
824*4882a593Smuzhiyun 	GTP_DEBUG("GTP driver exited.");
825*4882a593Smuzhiyun 	i2c_del_driver(&gt1x_ts_driver);
826*4882a593Smuzhiyun }
827*4882a593Smuzhiyun 
828*4882a593Smuzhiyun module_init(gt1x_ts_init);
829*4882a593Smuzhiyun module_exit(gt1x_ts_exit);
830*4882a593Smuzhiyun 
831*4882a593Smuzhiyun MODULE_DESCRIPTION("GTP Series Driver");
832*4882a593Smuzhiyun MODULE_LICENSE("GPL");
833*4882a593Smuzhiyun MODULE_IMPORT_NS(VFS_internal_I_am_really_a_filesystem_and_am_NOT_a_driver);
834