Linux Audio

Check our new training course

Loading...
v3.1
  1/*
  2 * Touchscreen driver for Dialog Semiconductor DA9034
  3 *
  4 * Copyright (C) 2006-2008 Marvell International Ltd.
  5 *	Fengwei Yin <fengwei.yin@marvell.com>
  6 *	Bin Yang  <bin.yang@marvell.com>
  7 *	Eric Miao <eric.miao@marvell.com>
  8 *
  9 * This program is free software; you can redistribute it and/or modify
 10 * it under the terms of the GNU General Public License version 2 as
 11 * published by the Free Software Foundation.
 12 */
 13
 14#include <linux/module.h>
 15#include <linux/kernel.h>
 16#include <linux/init.h>
 17#include <linux/delay.h>
 18#include <linux/platform_device.h>
 19#include <linux/input.h>
 20#include <linux/workqueue.h>
 21#include <linux/mfd/da903x.h>
 22#include <linux/slab.h>
 23
 24#define DA9034_MANUAL_CTRL	0x50
 25#define DA9034_LDO_ADC_EN	(1 << 4)
 26
 27#define DA9034_AUTO_CTRL1	0x51
 28
 29#define DA9034_AUTO_CTRL2	0x52
 30#define DA9034_AUTO_TSI_EN	(1 << 3)
 31#define DA9034_PEN_DETECT	(1 << 4)
 32
 33#define DA9034_TSI_CTRL1	0x53
 34#define DA9034_TSI_CTRL2	0x54
 35#define DA9034_TSI_X_MSB	0x6c
 36#define DA9034_TSI_Y_MSB	0x6d
 37#define DA9034_TSI_XY_LSB	0x6e
 38
 39enum {
 40	STATE_IDLE,	/* wait for pendown */
 41	STATE_BUSY,	/* TSI busy sampling */
 42	STATE_STOP,	/* sample available */
 43	STATE_WAIT,	/* Wait to start next sample */
 44};
 45
 46enum {
 47	EVENT_PEN_DOWN,
 48	EVENT_PEN_UP,
 49	EVENT_TSI_READY,
 50	EVENT_TIMEDOUT,
 51};
 52
 53struct da9034_touch {
 54	struct device		*da9034_dev;
 55	struct input_dev	*input_dev;
 56
 57	struct delayed_work	tsi_work;
 58	struct notifier_block	notifier;
 59
 60	int	state;
 61
 62	int	interval_ms;
 63	int	x_inverted;
 64	int	y_inverted;
 65
 66	int	last_x;
 67	int	last_y;
 68};
 69
 70static inline int is_pen_down(struct da9034_touch *touch)
 71{
 72	return da903x_query_status(touch->da9034_dev, DA9034_STATUS_PEN_DOWN);
 73}
 74
 75static inline int detect_pen_down(struct da9034_touch *touch, int on)
 76{
 77	if (on)
 78		return da903x_set_bits(touch->da9034_dev,
 79				DA9034_AUTO_CTRL2, DA9034_PEN_DETECT);
 80	else
 81		return da903x_clr_bits(touch->da9034_dev,
 82				DA9034_AUTO_CTRL2, DA9034_PEN_DETECT);
 83}
 84
 85static int read_tsi(struct da9034_touch *touch)
 86{
 87	uint8_t _x, _y, _v;
 88	int ret;
 89
 90	ret = da903x_read(touch->da9034_dev, DA9034_TSI_X_MSB, &_x);
 91	if (ret)
 92		return ret;
 93
 94	ret = da903x_read(touch->da9034_dev, DA9034_TSI_Y_MSB, &_y);
 95	if (ret)
 96		return ret;
 97
 98	ret = da903x_read(touch->da9034_dev, DA9034_TSI_XY_LSB, &_v);
 99	if (ret)
100		return ret;
101
102	touch->last_x = ((_x << 2) & 0x3fc) | (_v & 0x3);
103	touch->last_y = ((_y << 2) & 0x3fc) | ((_v & 0xc) >> 2);
104
105	return 0;
106}
107
108static inline int start_tsi(struct da9034_touch *touch)
109{
110	return da903x_set_bits(touch->da9034_dev,
111			DA9034_AUTO_CTRL2, DA9034_AUTO_TSI_EN);
112}
113
114static inline int stop_tsi(struct da9034_touch *touch)
115{
116	return da903x_clr_bits(touch->da9034_dev,
117			DA9034_AUTO_CTRL2, DA9034_AUTO_TSI_EN);
118}
119
120static inline void report_pen_down(struct da9034_touch *touch)
121{
122	int x = touch->last_x;
123	int y = touch->last_y;
124
125	x &= 0xfff;
126	if (touch->x_inverted)
127		x = 1024 - x;
128	y &= 0xfff;
129	if (touch->y_inverted)
130		y = 1024 - y;
131
132	input_report_abs(touch->input_dev, ABS_X, x);
133	input_report_abs(touch->input_dev, ABS_Y, y);
134	input_report_key(touch->input_dev, BTN_TOUCH, 1);
135
136	input_sync(touch->input_dev);
137}
138
139static inline void report_pen_up(struct da9034_touch *touch)
140{
141	input_report_key(touch->input_dev, BTN_TOUCH, 0);
142	input_sync(touch->input_dev);
143}
144
145static void da9034_event_handler(struct da9034_touch *touch, int event)
146{
147	int err;
148
149	switch (touch->state) {
150	case STATE_IDLE:
151		if (event != EVENT_PEN_DOWN)
152			break;
153
154		/* Enable auto measurement of the TSI, this will
155		 * automatically disable pen down detection
156		 */
157		err = start_tsi(touch);
158		if (err)
159			goto err_reset;
160
161		touch->state = STATE_BUSY;
162		break;
163
164	case STATE_BUSY:
165		if (event != EVENT_TSI_READY)
166			break;
167
168		err = read_tsi(touch);
169		if (err)
170			goto err_reset;
171
172		/* Disable auto measurement of the TSI, so that
173		 * pen down status will be available
174		 */
175		err = stop_tsi(touch);
176		if (err)
177			goto err_reset;
178
179		touch->state = STATE_STOP;
180
181		/* FIXME: PEN_{UP/DOWN} events are expected to be
182		 * available by stopping TSI, but this is found not
183		 * always true, delay and simulate such an event
184		 * here is more reliable
185		 */
186		mdelay(1);
187		da9034_event_handler(touch,
188				     is_pen_down(touch) ? EVENT_PEN_DOWN :
189							  EVENT_PEN_UP);
190		break;
191
192	case STATE_STOP:
193		if (event == EVENT_PEN_DOWN) {
194			report_pen_down(touch);
195			schedule_delayed_work(&touch->tsi_work,
196				msecs_to_jiffies(touch->interval_ms));
197			touch->state = STATE_WAIT;
198		}
199
200		if (event == EVENT_PEN_UP) {
201			report_pen_up(touch);
202			touch->state = STATE_IDLE;
203		}
204		break;
205
206	case STATE_WAIT:
207		if (event != EVENT_TIMEDOUT)
208			break;
209
210		if (is_pen_down(touch)) {
211			start_tsi(touch);
212			touch->state = STATE_BUSY;
213		} else {
214			report_pen_up(touch);
215			touch->state = STATE_IDLE;
216		}
217		break;
218	}
219	return;
220
221err_reset:
222	touch->state = STATE_IDLE;
223	stop_tsi(touch);
224	detect_pen_down(touch, 1);
225}
226
227static void da9034_tsi_work(struct work_struct *work)
228{
229	struct da9034_touch *touch =
230		container_of(work, struct da9034_touch, tsi_work.work);
231
232	da9034_event_handler(touch, EVENT_TIMEDOUT);
233}
234
235static int da9034_touch_notifier(struct notifier_block *nb,
236				 unsigned long event, void *data)
237{
238	struct da9034_touch *touch =
239		container_of(nb, struct da9034_touch, notifier);
240
241	if (event & DA9034_EVENT_TSI_READY)
242		da9034_event_handler(touch, EVENT_TSI_READY);
243
244	if ((event & DA9034_EVENT_PEN_DOWN) && touch->state == STATE_IDLE)
245		da9034_event_handler(touch, EVENT_PEN_DOWN);
246
247	return 0;
248}
249
250static int da9034_touch_open(struct input_dev *dev)
251{
252	struct da9034_touch *touch = input_get_drvdata(dev);
253	int ret;
254
255	ret = da903x_register_notifier(touch->da9034_dev, &touch->notifier,
256			DA9034_EVENT_PEN_DOWN | DA9034_EVENT_TSI_READY);
257	if (ret)
258		return -EBUSY;
259
260	/* Enable ADC LDO */
261	ret = da903x_set_bits(touch->da9034_dev,
262			DA9034_MANUAL_CTRL, DA9034_LDO_ADC_EN);
263	if (ret)
264		return ret;
265
266	/* TSI_DELAY: 3 slots, TSI_SKIP: 3 slots */
267	ret = da903x_write(touch->da9034_dev, DA9034_TSI_CTRL1, 0x1b);
268	if (ret)
269		return ret;
270
271	ret = da903x_write(touch->da9034_dev, DA9034_TSI_CTRL2, 0x00);
272	if (ret)
273		return ret;
274
275	touch->state = STATE_IDLE;
276	detect_pen_down(touch, 1);
277
278	return 0;
279}
280
281static void da9034_touch_close(struct input_dev *dev)
282{
283	struct da9034_touch *touch = input_get_drvdata(dev);
284
285	da903x_unregister_notifier(touch->da9034_dev, &touch->notifier,
286			DA9034_EVENT_PEN_DOWN | DA9034_EVENT_TSI_READY);
287
288	cancel_delayed_work_sync(&touch->tsi_work);
289
290	touch->state = STATE_IDLE;
291	stop_tsi(touch);
292	detect_pen_down(touch, 0);
293
294	/* Disable ADC LDO */
295	da903x_clr_bits(touch->da9034_dev,
296			DA9034_MANUAL_CTRL, DA9034_LDO_ADC_EN);
297}
298
299
300static int __devinit da9034_touch_probe(struct platform_device *pdev)
301{
302	struct da9034_touch_pdata *pdata = pdev->dev.platform_data;
303	struct da9034_touch *touch;
304	struct input_dev *input_dev;
305	int ret;
306
307	touch = kzalloc(sizeof(struct da9034_touch), GFP_KERNEL);
308	if (touch == NULL) {
 
309		dev_err(&pdev->dev, "failed to allocate driver data\n");
310		return -ENOMEM;
311	}
312
313	touch->da9034_dev = pdev->dev.parent;
314
315	if (pdata) {
316		touch->interval_ms	= pdata->interval_ms;
317		touch->x_inverted	= pdata->x_inverted;
318		touch->y_inverted	= pdata->y_inverted;
319	} else
320		/* fallback into default */
321		touch->interval_ms	= 10;
 
322
323	INIT_DELAYED_WORK(&touch->tsi_work, da9034_tsi_work);
324	touch->notifier.notifier_call = da9034_touch_notifier;
325
326	input_dev = input_allocate_device();
327	if (!input_dev) {
328		dev_err(&pdev->dev, "failed to allocate input device\n");
329		ret = -ENOMEM;
330		goto err_free_touch;
331	}
332
333	input_dev->name		= pdev->name;
334	input_dev->open		= da9034_touch_open;
335	input_dev->close	= da9034_touch_close;
336	input_dev->dev.parent	= &pdev->dev;
337
338	__set_bit(EV_ABS, input_dev->evbit);
339	__set_bit(ABS_X, input_dev->absbit);
340	__set_bit(ABS_Y, input_dev->absbit);
341	input_set_abs_params(input_dev, ABS_X, 0, 1023, 0, 0);
342	input_set_abs_params(input_dev, ABS_Y, 0, 1023, 0, 0);
343
344	__set_bit(EV_KEY, input_dev->evbit);
345	__set_bit(BTN_TOUCH, input_dev->keybit);
346
347	touch->input_dev = input_dev;
348	input_set_drvdata(input_dev, touch);
349
350	ret = input_register_device(input_dev);
351	if (ret)
352		goto err_free_input;
353
354	platform_set_drvdata(pdev, touch);
355	return 0;
356
357err_free_input:
358	input_free_device(input_dev);
359err_free_touch:
360	kfree(touch);
361	return ret;
362}
363
364static int __devexit da9034_touch_remove(struct platform_device *pdev)
365{
366	struct da9034_touch *touch = platform_get_drvdata(pdev);
367
368	input_unregister_device(touch->input_dev);
369	kfree(touch);
370
371	return 0;
372}
373
374static struct platform_driver da9034_touch_driver = {
375	.driver	= {
376		.name	= "da9034-touch",
377		.owner	= THIS_MODULE,
378	},
379	.probe		= da9034_touch_probe,
380	.remove		= __devexit_p(da9034_touch_remove),
381};
382
383static int __init da9034_touch_init(void)
384{
385	return platform_driver_register(&da9034_touch_driver);
386}
387module_init(da9034_touch_init);
388
389static void __exit da9034_touch_exit(void)
390{
391	platform_driver_unregister(&da9034_touch_driver);
392}
393module_exit(da9034_touch_exit);
394
395MODULE_DESCRIPTION("Touchscreen driver for Dialog Semiconductor DA9034");
396MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>, Bin Yang <bin.yang@marvell.com>");
397MODULE_LICENSE("GPL");
398MODULE_ALIAS("platform:da9034-touch");
v4.6
  1/*
  2 * Touchscreen driver for Dialog Semiconductor DA9034
  3 *
  4 * Copyright (C) 2006-2008 Marvell International Ltd.
  5 *	Fengwei Yin <fengwei.yin@marvell.com>
  6 *	Bin Yang  <bin.yang@marvell.com>
  7 *	Eric Miao <eric.miao@marvell.com>
  8 *
  9 * This program is free software; you can redistribute it and/or modify
 10 * it under the terms of the GNU General Public License version 2 as
 11 * published by the Free Software Foundation.
 12 */
 13
 14#include <linux/module.h>
 15#include <linux/kernel.h>
 
 16#include <linux/delay.h>
 17#include <linux/platform_device.h>
 18#include <linux/input.h>
 19#include <linux/workqueue.h>
 20#include <linux/mfd/da903x.h>
 21#include <linux/slab.h>
 22
 23#define DA9034_MANUAL_CTRL	0x50
 24#define DA9034_LDO_ADC_EN	(1 << 4)
 25
 26#define DA9034_AUTO_CTRL1	0x51
 27
 28#define DA9034_AUTO_CTRL2	0x52
 29#define DA9034_AUTO_TSI_EN	(1 << 3)
 30#define DA9034_PEN_DETECT	(1 << 4)
 31
 32#define DA9034_TSI_CTRL1	0x53
 33#define DA9034_TSI_CTRL2	0x54
 34#define DA9034_TSI_X_MSB	0x6c
 35#define DA9034_TSI_Y_MSB	0x6d
 36#define DA9034_TSI_XY_LSB	0x6e
 37
 38enum {
 39	STATE_IDLE,	/* wait for pendown */
 40	STATE_BUSY,	/* TSI busy sampling */
 41	STATE_STOP,	/* sample available */
 42	STATE_WAIT,	/* Wait to start next sample */
 43};
 44
 45enum {
 46	EVENT_PEN_DOWN,
 47	EVENT_PEN_UP,
 48	EVENT_TSI_READY,
 49	EVENT_TIMEDOUT,
 50};
 51
 52struct da9034_touch {
 53	struct device		*da9034_dev;
 54	struct input_dev	*input_dev;
 55
 56	struct delayed_work	tsi_work;
 57	struct notifier_block	notifier;
 58
 59	int	state;
 60
 61	int	interval_ms;
 62	int	x_inverted;
 63	int	y_inverted;
 64
 65	int	last_x;
 66	int	last_y;
 67};
 68
 69static inline int is_pen_down(struct da9034_touch *touch)
 70{
 71	return da903x_query_status(touch->da9034_dev, DA9034_STATUS_PEN_DOWN);
 72}
 73
 74static inline int detect_pen_down(struct da9034_touch *touch, int on)
 75{
 76	if (on)
 77		return da903x_set_bits(touch->da9034_dev,
 78				DA9034_AUTO_CTRL2, DA9034_PEN_DETECT);
 79	else
 80		return da903x_clr_bits(touch->da9034_dev,
 81				DA9034_AUTO_CTRL2, DA9034_PEN_DETECT);
 82}
 83
 84static int read_tsi(struct da9034_touch *touch)
 85{
 86	uint8_t _x, _y, _v;
 87	int ret;
 88
 89	ret = da903x_read(touch->da9034_dev, DA9034_TSI_X_MSB, &_x);
 90	if (ret)
 91		return ret;
 92
 93	ret = da903x_read(touch->da9034_dev, DA9034_TSI_Y_MSB, &_y);
 94	if (ret)
 95		return ret;
 96
 97	ret = da903x_read(touch->da9034_dev, DA9034_TSI_XY_LSB, &_v);
 98	if (ret)
 99		return ret;
100
101	touch->last_x = ((_x << 2) & 0x3fc) | (_v & 0x3);
102	touch->last_y = ((_y << 2) & 0x3fc) | ((_v & 0xc) >> 2);
103
104	return 0;
105}
106
107static inline int start_tsi(struct da9034_touch *touch)
108{
109	return da903x_set_bits(touch->da9034_dev,
110			DA9034_AUTO_CTRL2, DA9034_AUTO_TSI_EN);
111}
112
113static inline int stop_tsi(struct da9034_touch *touch)
114{
115	return da903x_clr_bits(touch->da9034_dev,
116			DA9034_AUTO_CTRL2, DA9034_AUTO_TSI_EN);
117}
118
119static inline void report_pen_down(struct da9034_touch *touch)
120{
121	int x = touch->last_x;
122	int y = touch->last_y;
123
124	x &= 0xfff;
125	if (touch->x_inverted)
126		x = 1024 - x;
127	y &= 0xfff;
128	if (touch->y_inverted)
129		y = 1024 - y;
130
131	input_report_abs(touch->input_dev, ABS_X, x);
132	input_report_abs(touch->input_dev, ABS_Y, y);
133	input_report_key(touch->input_dev, BTN_TOUCH, 1);
134
135	input_sync(touch->input_dev);
136}
137
138static inline void report_pen_up(struct da9034_touch *touch)
139{
140	input_report_key(touch->input_dev, BTN_TOUCH, 0);
141	input_sync(touch->input_dev);
142}
143
144static void da9034_event_handler(struct da9034_touch *touch, int event)
145{
146	int err;
147
148	switch (touch->state) {
149	case STATE_IDLE:
150		if (event != EVENT_PEN_DOWN)
151			break;
152
153		/* Enable auto measurement of the TSI, this will
154		 * automatically disable pen down detection
155		 */
156		err = start_tsi(touch);
157		if (err)
158			goto err_reset;
159
160		touch->state = STATE_BUSY;
161		break;
162
163	case STATE_BUSY:
164		if (event != EVENT_TSI_READY)
165			break;
166
167		err = read_tsi(touch);
168		if (err)
169			goto err_reset;
170
171		/* Disable auto measurement of the TSI, so that
172		 * pen down status will be available
173		 */
174		err = stop_tsi(touch);
175		if (err)
176			goto err_reset;
177
178		touch->state = STATE_STOP;
179
180		/* FIXME: PEN_{UP/DOWN} events are expected to be
181		 * available by stopping TSI, but this is found not
182		 * always true, delay and simulate such an event
183		 * here is more reliable
184		 */
185		mdelay(1);
186		da9034_event_handler(touch,
187				     is_pen_down(touch) ? EVENT_PEN_DOWN :
188							  EVENT_PEN_UP);
189		break;
190
191	case STATE_STOP:
192		if (event == EVENT_PEN_DOWN) {
193			report_pen_down(touch);
194			schedule_delayed_work(&touch->tsi_work,
195				msecs_to_jiffies(touch->interval_ms));
196			touch->state = STATE_WAIT;
197		}
198
199		if (event == EVENT_PEN_UP) {
200			report_pen_up(touch);
201			touch->state = STATE_IDLE;
202		}
203		break;
204
205	case STATE_WAIT:
206		if (event != EVENT_TIMEDOUT)
207			break;
208
209		if (is_pen_down(touch)) {
210			start_tsi(touch);
211			touch->state = STATE_BUSY;
212		} else {
213			report_pen_up(touch);
214			touch->state = STATE_IDLE;
215		}
216		break;
217	}
218	return;
219
220err_reset:
221	touch->state = STATE_IDLE;
222	stop_tsi(touch);
223	detect_pen_down(touch, 1);
224}
225
226static void da9034_tsi_work(struct work_struct *work)
227{
228	struct da9034_touch *touch =
229		container_of(work, struct da9034_touch, tsi_work.work);
230
231	da9034_event_handler(touch, EVENT_TIMEDOUT);
232}
233
234static int da9034_touch_notifier(struct notifier_block *nb,
235				 unsigned long event, void *data)
236{
237	struct da9034_touch *touch =
238		container_of(nb, struct da9034_touch, notifier);
239
240	if (event & DA9034_EVENT_TSI_READY)
241		da9034_event_handler(touch, EVENT_TSI_READY);
242
243	if ((event & DA9034_EVENT_PEN_DOWN) && touch->state == STATE_IDLE)
244		da9034_event_handler(touch, EVENT_PEN_DOWN);
245
246	return 0;
247}
248
249static int da9034_touch_open(struct input_dev *dev)
250{
251	struct da9034_touch *touch = input_get_drvdata(dev);
252	int ret;
253
254	ret = da903x_register_notifier(touch->da9034_dev, &touch->notifier,
255			DA9034_EVENT_PEN_DOWN | DA9034_EVENT_TSI_READY);
256	if (ret)
257		return -EBUSY;
258
259	/* Enable ADC LDO */
260	ret = da903x_set_bits(touch->da9034_dev,
261			DA9034_MANUAL_CTRL, DA9034_LDO_ADC_EN);
262	if (ret)
263		return ret;
264
265	/* TSI_DELAY: 3 slots, TSI_SKIP: 3 slots */
266	ret = da903x_write(touch->da9034_dev, DA9034_TSI_CTRL1, 0x1b);
267	if (ret)
268		return ret;
269
270	ret = da903x_write(touch->da9034_dev, DA9034_TSI_CTRL2, 0x00);
271	if (ret)
272		return ret;
273
274	touch->state = STATE_IDLE;
275	detect_pen_down(touch, 1);
276
277	return 0;
278}
279
280static void da9034_touch_close(struct input_dev *dev)
281{
282	struct da9034_touch *touch = input_get_drvdata(dev);
283
284	da903x_unregister_notifier(touch->da9034_dev, &touch->notifier,
285			DA9034_EVENT_PEN_DOWN | DA9034_EVENT_TSI_READY);
286
287	cancel_delayed_work_sync(&touch->tsi_work);
288
289	touch->state = STATE_IDLE;
290	stop_tsi(touch);
291	detect_pen_down(touch, 0);
292
293	/* Disable ADC LDO */
294	da903x_clr_bits(touch->da9034_dev,
295			DA9034_MANUAL_CTRL, DA9034_LDO_ADC_EN);
296}
297
298
299static int da9034_touch_probe(struct platform_device *pdev)
300{
301	struct da9034_touch_pdata *pdata = dev_get_platdata(&pdev->dev);
302	struct da9034_touch *touch;
303	struct input_dev *input_dev;
304	int error;
305
306	touch = devm_kzalloc(&pdev->dev, sizeof(struct da9034_touch),
307			     GFP_KERNEL);
308	if (!touch) {
309		dev_err(&pdev->dev, "failed to allocate driver data\n");
310		return -ENOMEM;
311	}
312
313	touch->da9034_dev = pdev->dev.parent;
314
315	if (pdata) {
316		touch->interval_ms	= pdata->interval_ms;
317		touch->x_inverted	= pdata->x_inverted;
318		touch->y_inverted	= pdata->y_inverted;
319	} else {
320		/* fallback into default */
321		touch->interval_ms	= 10;
322	}
323
324	INIT_DELAYED_WORK(&touch->tsi_work, da9034_tsi_work);
325	touch->notifier.notifier_call = da9034_touch_notifier;
326
327	input_dev = devm_input_allocate_device(&pdev->dev);
328	if (!input_dev) {
329		dev_err(&pdev->dev, "failed to allocate input device\n");
330		return -ENOMEM;
 
331	}
332
333	input_dev->name		= pdev->name;
334	input_dev->open		= da9034_touch_open;
335	input_dev->close	= da9034_touch_close;
336	input_dev->dev.parent	= &pdev->dev;
337
338	__set_bit(EV_ABS, input_dev->evbit);
339	__set_bit(ABS_X, input_dev->absbit);
340	__set_bit(ABS_Y, input_dev->absbit);
341	input_set_abs_params(input_dev, ABS_X, 0, 1023, 0, 0);
342	input_set_abs_params(input_dev, ABS_Y, 0, 1023, 0, 0);
343
344	__set_bit(EV_KEY, input_dev->evbit);
345	__set_bit(BTN_TOUCH, input_dev->keybit);
346
347	touch->input_dev = input_dev;
348	input_set_drvdata(input_dev, touch);
349
350	error = input_register_device(input_dev);
351	if (error)
352		return error;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
353
354	return 0;
355}
356
357static struct platform_driver da9034_touch_driver = {
358	.driver	= {
359		.name	= "da9034-touch",
 
360	},
361	.probe		= da9034_touch_probe,
 
362};
363module_platform_driver(da9034_touch_driver);
 
 
 
 
 
 
 
 
 
 
 
364
365MODULE_DESCRIPTION("Touchscreen driver for Dialog Semiconductor DA9034");
366MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>, Bin Yang <bin.yang@marvell.com>");
367MODULE_LICENSE("GPL");
368MODULE_ALIAS("platform:da9034-touch");