xref: /linux/drivers/input/touchscreen/cy8ctmg110_ts.c (revision 60347c194acec7ff1b4291ac8e62a5345244c2ee)
1*60347c19SSamuli Konttila /*
2*60347c19SSamuli Konttila  * Driver for cypress touch screen controller
3*60347c19SSamuli Konttila  *
4*60347c19SSamuli Konttila  * Copyright (c) 2009 Aava Mobile
5*60347c19SSamuli Konttila  *
6*60347c19SSamuli Konttila  * Some cleanups by Alan Cox <alan@linux.intel.com>
7*60347c19SSamuli Konttila  *
8*60347c19SSamuli Konttila  * This program is free software; you can redistribute it and/or modify
9*60347c19SSamuli Konttila  * it under the terms of the GNU General Public License version 2 as
10*60347c19SSamuli Konttila  * published by the Free Software Foundation.
11*60347c19SSamuli Konttila  *
12*60347c19SSamuli Konttila  * This program is distributed in the hope that it will be useful,
13*60347c19SSamuli Konttila  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14*60347c19SSamuli Konttila  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*60347c19SSamuli Konttila  * GNU General Public License for more details.
16*60347c19SSamuli Konttila  *
17*60347c19SSamuli Konttila  * You should have received a copy of the GNU General Public License
18*60347c19SSamuli Konttila  * along with this program; if not, write to the Free Software
19*60347c19SSamuli Konttila  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20*60347c19SSamuli Konttila  */
21*60347c19SSamuli Konttila 
22*60347c19SSamuli Konttila #include <linux/module.h>
23*60347c19SSamuli Konttila #include <linux/kernel.h>
24*60347c19SSamuli Konttila #include <linux/input.h>
25*60347c19SSamuli Konttila #include <linux/slab.h>
26*60347c19SSamuli Konttila #include <linux/interrupt.h>
27*60347c19SSamuli Konttila #include <linux/io.h>
28*60347c19SSamuli Konttila #include <linux/i2c.h>
29*60347c19SSamuli Konttila #include <linux/gpio.h>
30*60347c19SSamuli Konttila #include <linux/input/cy8ctmg110_pdata.h>
31*60347c19SSamuli Konttila 
32*60347c19SSamuli Konttila #define CY8CTMG110_DRIVER_NAME      "cy8ctmg110"
33*60347c19SSamuli Konttila 
34*60347c19SSamuli Konttila /* Touch coordinates */
35*60347c19SSamuli Konttila #define CY8CTMG110_X_MIN		0
36*60347c19SSamuli Konttila #define CY8CTMG110_Y_MIN		0
37*60347c19SSamuli Konttila #define CY8CTMG110_X_MAX		759
38*60347c19SSamuli Konttila #define CY8CTMG110_Y_MAX		465
39*60347c19SSamuli Konttila 
40*60347c19SSamuli Konttila 
41*60347c19SSamuli Konttila /* cy8ctmg110 register definitions */
42*60347c19SSamuli Konttila #define CY8CTMG110_TOUCH_WAKEUP_TIME	0
43*60347c19SSamuli Konttila #define CY8CTMG110_TOUCH_SLEEP_TIME	2
44*60347c19SSamuli Konttila #define CY8CTMG110_TOUCH_X1		3
45*60347c19SSamuli Konttila #define CY8CTMG110_TOUCH_Y1		5
46*60347c19SSamuli Konttila #define CY8CTMG110_TOUCH_X2		7
47*60347c19SSamuli Konttila #define CY8CTMG110_TOUCH_Y2		9
48*60347c19SSamuli Konttila #define CY8CTMG110_FINGERS		11
49*60347c19SSamuli Konttila #define CY8CTMG110_GESTURE		12
50*60347c19SSamuli Konttila #define CY8CTMG110_REG_MAX		13
51*60347c19SSamuli Konttila 
52*60347c19SSamuli Konttila 
53*60347c19SSamuli Konttila /*
54*60347c19SSamuli Konttila  * The touch driver structure.
55*60347c19SSamuli Konttila  */
56*60347c19SSamuli Konttila struct cy8ctmg110 {
57*60347c19SSamuli Konttila 	struct input_dev *input;
58*60347c19SSamuli Konttila 	char phys[32];
59*60347c19SSamuli Konttila 	struct i2c_client *client;
60*60347c19SSamuli Konttila 	int reset_pin;
61*60347c19SSamuli Konttila 	int irq_pin;
62*60347c19SSamuli Konttila };
63*60347c19SSamuli Konttila 
64*60347c19SSamuli Konttila /*
65*60347c19SSamuli Konttila  * cy8ctmg110_power is the routine that is called when touch hardware
66*60347c19SSamuli Konttila  * will powered off or on.
67*60347c19SSamuli Konttila  */
68*60347c19SSamuli Konttila static void cy8ctmg110_power(struct cy8ctmg110 *ts, bool poweron)
69*60347c19SSamuli Konttila {
70*60347c19SSamuli Konttila 	if (ts->reset_pin)
71*60347c19SSamuli Konttila 		gpio_direction_output(ts->reset_pin, 1 - poweron);
72*60347c19SSamuli Konttila }
73*60347c19SSamuli Konttila 
74*60347c19SSamuli Konttila static int cy8ctmg110_write_regs(struct cy8ctmg110 *tsc, unsigned char reg,
75*60347c19SSamuli Konttila 		unsigned char len, unsigned char *value)
76*60347c19SSamuli Konttila {
77*60347c19SSamuli Konttila 	struct i2c_client *client = tsc->client;
78*60347c19SSamuli Konttila 	unsigned int ret;
79*60347c19SSamuli Konttila 	unsigned char i2c_data[6];
80*60347c19SSamuli Konttila 
81*60347c19SSamuli Konttila 	BUG_ON(len > 5);
82*60347c19SSamuli Konttila 
83*60347c19SSamuli Konttila 	i2c_data[0] = reg;
84*60347c19SSamuli Konttila 	memcpy(i2c_data + 1, value, len);
85*60347c19SSamuli Konttila 
86*60347c19SSamuli Konttila 	ret = i2c_master_send(client, i2c_data, len + 1);
87*60347c19SSamuli Konttila 	if (ret != 1) {
88*60347c19SSamuli Konttila 		dev_err(&client->dev, "i2c write data cmd failed\n");
89*60347c19SSamuli Konttila 		return ret;
90*60347c19SSamuli Konttila 	}
91*60347c19SSamuli Konttila 
92*60347c19SSamuli Konttila 	return 0;
93*60347c19SSamuli Konttila }
94*60347c19SSamuli Konttila 
95*60347c19SSamuli Konttila static int cy8ctmg110_read_regs(struct cy8ctmg110 *tsc,
96*60347c19SSamuli Konttila 		unsigned char *data, unsigned char len, unsigned char cmd)
97*60347c19SSamuli Konttila {
98*60347c19SSamuli Konttila 	struct i2c_client *client = tsc->client;
99*60347c19SSamuli Konttila 	unsigned int ret;
100*60347c19SSamuli Konttila 	struct i2c_msg msg[2] = {
101*60347c19SSamuli Konttila 		/* first write slave position to i2c devices */
102*60347c19SSamuli Konttila 		{ client->addr, 0, 1, &cmd },
103*60347c19SSamuli Konttila 		/* Second read data from position */
104*60347c19SSamuli Konttila 		{ client->addr, I2C_M_RD, len, data }
105*60347c19SSamuli Konttila 	};
106*60347c19SSamuli Konttila 
107*60347c19SSamuli Konttila 	ret = i2c_transfer(client->adapter, msg, 2);
108*60347c19SSamuli Konttila 	if (ret < 0)
109*60347c19SSamuli Konttila 		return ret;
110*60347c19SSamuli Konttila 
111*60347c19SSamuli Konttila 	return 0;
112*60347c19SSamuli Konttila }
113*60347c19SSamuli Konttila 
114*60347c19SSamuli Konttila static int cy8ctmg110_touch_pos(struct cy8ctmg110 *tsc)
115*60347c19SSamuli Konttila {
116*60347c19SSamuli Konttila 	struct input_dev *input = tsc->input;
117*60347c19SSamuli Konttila 	unsigned char reg_p[CY8CTMG110_REG_MAX];
118*60347c19SSamuli Konttila 	int x, y;
119*60347c19SSamuli Konttila 
120*60347c19SSamuli Konttila 	memset(reg_p, 0, CY8CTMG110_REG_MAX);
121*60347c19SSamuli Konttila 
122*60347c19SSamuli Konttila 	/* Reading coordinates */
123*60347c19SSamuli Konttila 	if (cy8ctmg110_read_regs(tsc, reg_p, 9, CY8CTMG110_TOUCH_X1) != 0)
124*60347c19SSamuli Konttila 		return -EIO;
125*60347c19SSamuli Konttila 
126*60347c19SSamuli Konttila 	y = reg_p[2] << 8 | reg_p[3];
127*60347c19SSamuli Konttila 	x = reg_p[0] << 8 | reg_p[1];
128*60347c19SSamuli Konttila 
129*60347c19SSamuli Konttila 	/* Number of touch */
130*60347c19SSamuli Konttila 	if (reg_p[8] == 0) {
131*60347c19SSamuli Konttila 		input_report_key(input, BTN_TOUCH, 0);
132*60347c19SSamuli Konttila 	} else  {
133*60347c19SSamuli Konttila 		input_report_key(input, BTN_TOUCH, 1);
134*60347c19SSamuli Konttila 		input_report_abs(input, ABS_X, x);
135*60347c19SSamuli Konttila 		input_report_abs(input, ABS_Y, y);
136*60347c19SSamuli Konttila 	}
137*60347c19SSamuli Konttila 
138*60347c19SSamuli Konttila 	input_sync(input);
139*60347c19SSamuli Konttila 
140*60347c19SSamuli Konttila 	return 0;
141*60347c19SSamuli Konttila }
142*60347c19SSamuli Konttila 
143*60347c19SSamuli Konttila static int cy8ctmg110_set_sleepmode(struct cy8ctmg110 *ts, bool sleep)
144*60347c19SSamuli Konttila {
145*60347c19SSamuli Konttila 	unsigned char reg_p[3];
146*60347c19SSamuli Konttila 
147*60347c19SSamuli Konttila 	if (sleep) {
148*60347c19SSamuli Konttila 		reg_p[0] = 0x00;
149*60347c19SSamuli Konttila 		reg_p[1] = 0xff;
150*60347c19SSamuli Konttila 		reg_p[2] = 5;
151*60347c19SSamuli Konttila 	} else {
152*60347c19SSamuli Konttila 		reg_p[0] = 0x10;
153*60347c19SSamuli Konttila 		reg_p[1] = 0xff;
154*60347c19SSamuli Konttila 		reg_p[2] = 0;
155*60347c19SSamuli Konttila 	}
156*60347c19SSamuli Konttila 
157*60347c19SSamuli Konttila 	return cy8ctmg110_write_regs(ts, CY8CTMG110_TOUCH_WAKEUP_TIME, 3, reg_p);
158*60347c19SSamuli Konttila }
159*60347c19SSamuli Konttila 
160*60347c19SSamuli Konttila static irqreturn_t cy8ctmg110_irq_thread(int irq, void *dev_id)
161*60347c19SSamuli Konttila {
162*60347c19SSamuli Konttila 	struct cy8ctmg110 *tsc = dev_id;
163*60347c19SSamuli Konttila 
164*60347c19SSamuli Konttila 	cy8ctmg110_touch_pos(tsc);
165*60347c19SSamuli Konttila 
166*60347c19SSamuli Konttila 	return IRQ_HANDLED;
167*60347c19SSamuli Konttila }
168*60347c19SSamuli Konttila 
169*60347c19SSamuli Konttila static int __devinit cy8ctmg110_probe(struct i2c_client *client,
170*60347c19SSamuli Konttila 					const struct i2c_device_id *id)
171*60347c19SSamuli Konttila {
172*60347c19SSamuli Konttila 	const struct cy8ctmg110_pdata *pdata = client->dev.platform_data;
173*60347c19SSamuli Konttila 	struct cy8ctmg110 *ts;
174*60347c19SSamuli Konttila 	struct input_dev *input_dev;
175*60347c19SSamuli Konttila 	int err;
176*60347c19SSamuli Konttila 
177*60347c19SSamuli Konttila 	/* No pdata no way forward */
178*60347c19SSamuli Konttila 	if (pdata == NULL) {
179*60347c19SSamuli Konttila 		dev_err(&client->dev, "no pdata\n");
180*60347c19SSamuli Konttila 		return -ENODEV;
181*60347c19SSamuli Konttila 	}
182*60347c19SSamuli Konttila 
183*60347c19SSamuli Konttila 	if (!i2c_check_functionality(client->adapter,
184*60347c19SSamuli Konttila 					I2C_FUNC_SMBUS_READ_WORD_DATA))
185*60347c19SSamuli Konttila 		return -EIO;
186*60347c19SSamuli Konttila 
187*60347c19SSamuli Konttila 	ts = kzalloc(sizeof(struct cy8ctmg110), GFP_KERNEL);
188*60347c19SSamuli Konttila 	input_dev = input_allocate_device();
189*60347c19SSamuli Konttila 	if (!ts || !input_dev) {
190*60347c19SSamuli Konttila 		err = -ENOMEM;
191*60347c19SSamuli Konttila 		goto err_free_mem;
192*60347c19SSamuli Konttila 	}
193*60347c19SSamuli Konttila 
194*60347c19SSamuli Konttila 	ts->client = client;
195*60347c19SSamuli Konttila 	ts->input = input_dev;
196*60347c19SSamuli Konttila 
197*60347c19SSamuli Konttila 	snprintf(ts->phys, sizeof(ts->phys),
198*60347c19SSamuli Konttila 		 "%s/input0", dev_name(&client->dev));
199*60347c19SSamuli Konttila 
200*60347c19SSamuli Konttila 	input_dev->name = CY8CTMG110_DRIVER_NAME " Touchscreen";
201*60347c19SSamuli Konttila 	input_dev->phys = ts->phys;
202*60347c19SSamuli Konttila 	input_dev->id.bustype = BUS_I2C;
203*60347c19SSamuli Konttila 	input_dev->dev.parent = &client->dev;
204*60347c19SSamuli Konttila 
205*60347c19SSamuli Konttila 	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
206*60347c19SSamuli Konttila 	input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
207*60347c19SSamuli Konttila 
208*60347c19SSamuli Konttila 	input_set_abs_params(input_dev, ABS_X,
209*60347c19SSamuli Konttila 			CY8CTMG110_X_MIN, CY8CTMG110_X_MAX, 0, 0);
210*60347c19SSamuli Konttila 	input_set_abs_params(input_dev, ABS_Y,
211*60347c19SSamuli Konttila 			CY8CTMG110_Y_MIN, CY8CTMG110_Y_MAX, 0, 0);
212*60347c19SSamuli Konttila 
213*60347c19SSamuli Konttila 	if (ts->reset_pin) {
214*60347c19SSamuli Konttila 		err = gpio_request(ts->reset_pin, NULL);
215*60347c19SSamuli Konttila 		if (err) {
216*60347c19SSamuli Konttila 			dev_err(&client->dev,
217*60347c19SSamuli Konttila 				"Unable to request GPIO pin %d.\n",
218*60347c19SSamuli Konttila 				ts->reset_pin);
219*60347c19SSamuli Konttila 			goto err_free_mem;
220*60347c19SSamuli Konttila 		}
221*60347c19SSamuli Konttila 	}
222*60347c19SSamuli Konttila 
223*60347c19SSamuli Konttila 	cy8ctmg110_power(ts, true);
224*60347c19SSamuli Konttila 	cy8ctmg110_set_sleepmode(ts, false);
225*60347c19SSamuli Konttila 
226*60347c19SSamuli Konttila 	err = gpio_request(ts->irq_pin, "touch_irq_key");
227*60347c19SSamuli Konttila 	if (err < 0) {
228*60347c19SSamuli Konttila 		dev_err(&client->dev,
229*60347c19SSamuli Konttila 			"Failed to request GPIO %d, error %d\n",
230*60347c19SSamuli Konttila 			ts->irq_pin, err);
231*60347c19SSamuli Konttila 		goto err_shutoff_device;
232*60347c19SSamuli Konttila 	}
233*60347c19SSamuli Konttila 
234*60347c19SSamuli Konttila 	err = gpio_direction_input(ts->irq_pin);
235*60347c19SSamuli Konttila 	if (err < 0) {
236*60347c19SSamuli Konttila 		dev_err(&client->dev,
237*60347c19SSamuli Konttila 			"Failed to configure input direction for GPIO %d, error %d\n",
238*60347c19SSamuli Konttila 			ts->irq_pin, err);
239*60347c19SSamuli Konttila 		goto err_free_irq_gpio;
240*60347c19SSamuli Konttila 	}
241*60347c19SSamuli Konttila 
242*60347c19SSamuli Konttila 	client->irq = gpio_to_irq(ts->irq_pin);
243*60347c19SSamuli Konttila 	if (client->irq < 0) {
244*60347c19SSamuli Konttila 		err = client->irq;
245*60347c19SSamuli Konttila 		dev_err(&client->dev,
246*60347c19SSamuli Konttila 			"Unable to get irq number for GPIO %d, error %d\n",
247*60347c19SSamuli Konttila 			ts->irq_pin, err);
248*60347c19SSamuli Konttila 		goto err_free_irq_gpio;
249*60347c19SSamuli Konttila 	}
250*60347c19SSamuli Konttila 
251*60347c19SSamuli Konttila 	err = request_threaded_irq(client->irq, NULL, cy8ctmg110_irq_thread,
252*60347c19SSamuli Konttila 				   IRQF_TRIGGER_RISING, "touch_reset_key", ts);
253*60347c19SSamuli Konttila 	if (err < 0) {
254*60347c19SSamuli Konttila 		dev_err(&client->dev,
255*60347c19SSamuli Konttila 			"irq %d busy? error %d\n", client->irq, err);
256*60347c19SSamuli Konttila 		goto err_free_irq_gpio;
257*60347c19SSamuli Konttila 	}
258*60347c19SSamuli Konttila 
259*60347c19SSamuli Konttila 	err = input_register_device(input_dev);
260*60347c19SSamuli Konttila 	if (err)
261*60347c19SSamuli Konttila 		goto err_free_irq;
262*60347c19SSamuli Konttila 
263*60347c19SSamuli Konttila 	i2c_set_clientdata(client, ts);
264*60347c19SSamuli Konttila 	device_init_wakeup(&client->dev, 1);
265*60347c19SSamuli Konttila 	return 0;
266*60347c19SSamuli Konttila 
267*60347c19SSamuli Konttila err_free_irq:
268*60347c19SSamuli Konttila 	free_irq(client->irq, ts);
269*60347c19SSamuli Konttila err_free_irq_gpio:
270*60347c19SSamuli Konttila 	gpio_free(ts->irq_pin);
271*60347c19SSamuli Konttila err_shutoff_device:
272*60347c19SSamuli Konttila 	cy8ctmg110_set_sleepmode(ts, true);
273*60347c19SSamuli Konttila 	cy8ctmg110_power(ts, false);
274*60347c19SSamuli Konttila 	if (ts->reset_pin)
275*60347c19SSamuli Konttila 		gpio_free(ts->reset_pin);
276*60347c19SSamuli Konttila err_free_mem:
277*60347c19SSamuli Konttila 	input_free_device(input_dev);
278*60347c19SSamuli Konttila 	kfree(ts);
279*60347c19SSamuli Konttila 	return err;
280*60347c19SSamuli Konttila }
281*60347c19SSamuli Konttila 
282*60347c19SSamuli Konttila #ifdef CONFIG_PM
283*60347c19SSamuli Konttila static int cy8ctmg110_suspend(struct i2c_client *client, pm_message_t mesg)
284*60347c19SSamuli Konttila {
285*60347c19SSamuli Konttila 	struct cy8ctmg110 *ts = i2c_get_clientdata(client);
286*60347c19SSamuli Konttila 
287*60347c19SSamuli Konttila 	if (device_may_wakeup(&client->dev))
288*60347c19SSamuli Konttila 		enable_irq_wake(client->irq);
289*60347c19SSamuli Konttila 	else {
290*60347c19SSamuli Konttila 		cy8ctmg110_set_sleepmode(ts, true);
291*60347c19SSamuli Konttila 		cy8ctmg110_power(ts, false);
292*60347c19SSamuli Konttila 	}
293*60347c19SSamuli Konttila 	return 0;
294*60347c19SSamuli Konttila }
295*60347c19SSamuli Konttila 
296*60347c19SSamuli Konttila static int cy8ctmg110_resume(struct i2c_client *client)
297*60347c19SSamuli Konttila {
298*60347c19SSamuli Konttila 	struct cy8ctmg110 *ts = i2c_get_clientdata(client);
299*60347c19SSamuli Konttila 
300*60347c19SSamuli Konttila 	if (device_may_wakeup(&client->dev))
301*60347c19SSamuli Konttila 		disable_irq_wake(client->irq);
302*60347c19SSamuli Konttila 	else {
303*60347c19SSamuli Konttila 		cy8ctmg110_power(ts, true);
304*60347c19SSamuli Konttila 		cy8ctmg110_set_sleepmode(ts, false);
305*60347c19SSamuli Konttila 	}
306*60347c19SSamuli Konttila 	return 0;
307*60347c19SSamuli Konttila }
308*60347c19SSamuli Konttila #endif
309*60347c19SSamuli Konttila 
310*60347c19SSamuli Konttila static int __devexit cy8ctmg110_remove(struct i2c_client *client)
311*60347c19SSamuli Konttila {
312*60347c19SSamuli Konttila 	struct cy8ctmg110 *ts = i2c_get_clientdata(client);
313*60347c19SSamuli Konttila 
314*60347c19SSamuli Konttila 	cy8ctmg110_set_sleepmode(ts, true);
315*60347c19SSamuli Konttila 	cy8ctmg110_power(ts, false);
316*60347c19SSamuli Konttila 
317*60347c19SSamuli Konttila 	free_irq(client->irq, ts);
318*60347c19SSamuli Konttila 	input_unregister_device(ts->input);
319*60347c19SSamuli Konttila 	gpio_free(ts->irq_pin);
320*60347c19SSamuli Konttila 	if (ts->reset_pin)
321*60347c19SSamuli Konttila 		gpio_free(ts->reset_pin);
322*60347c19SSamuli Konttila 	kfree(ts);
323*60347c19SSamuli Konttila 
324*60347c19SSamuli Konttila 	return 0;
325*60347c19SSamuli Konttila }
326*60347c19SSamuli Konttila 
327*60347c19SSamuli Konttila static struct i2c_device_id cy8ctmg110_idtable[] = {
328*60347c19SSamuli Konttila 	{ CY8CTMG110_DRIVER_NAME, 1 },
329*60347c19SSamuli Konttila 	{ }
330*60347c19SSamuli Konttila };
331*60347c19SSamuli Konttila 
332*60347c19SSamuli Konttila MODULE_DEVICE_TABLE(i2c, cy8ctmg110_idtable);
333*60347c19SSamuli Konttila 
334*60347c19SSamuli Konttila static struct i2c_driver cy8ctmg110_driver = {
335*60347c19SSamuli Konttila 	.driver		= {
336*60347c19SSamuli Konttila 		.owner	= THIS_MODULE,
337*60347c19SSamuli Konttila 		.name	= CY8CTMG110_DRIVER_NAME,
338*60347c19SSamuli Konttila 	},
339*60347c19SSamuli Konttila 	.id_table	= cy8ctmg110_idtable,
340*60347c19SSamuli Konttila 	.probe		= cy8ctmg110_probe,
341*60347c19SSamuli Konttila 	.remove		= __devexit_p(cy8ctmg110_remove),
342*60347c19SSamuli Konttila #ifdef CONFIG_PM
343*60347c19SSamuli Konttila 	.suspend	= cy8ctmg110_suspend,
344*60347c19SSamuli Konttila 	.resume		= cy8ctmg110_resume,
345*60347c19SSamuli Konttila #endif
346*60347c19SSamuli Konttila };
347*60347c19SSamuli Konttila 
348*60347c19SSamuli Konttila static int __init cy8ctmg110_init(void)
349*60347c19SSamuli Konttila {
350*60347c19SSamuli Konttila 	return i2c_add_driver(&cy8ctmg110_driver);
351*60347c19SSamuli Konttila }
352*60347c19SSamuli Konttila 
353*60347c19SSamuli Konttila static void __exit cy8ctmg110_exit(void)
354*60347c19SSamuli Konttila {
355*60347c19SSamuli Konttila 	i2c_del_driver(&cy8ctmg110_driver);
356*60347c19SSamuli Konttila }
357*60347c19SSamuli Konttila 
358*60347c19SSamuli Konttila module_init(cy8ctmg110_init);
359*60347c19SSamuli Konttila module_exit(cy8ctmg110_exit);
360*60347c19SSamuli Konttila 
361*60347c19SSamuli Konttila MODULE_AUTHOR("Samuli Konttila <samuli.konttila@aavamobile.com>");
362*60347c19SSamuli Konttila MODULE_DESCRIPTION("cy8ctmg110 TouchScreen Driver");
363*60347c19SSamuli Konttila MODULE_LICENSE("GPL v2");
364