2 * intel_mid_touch.c - Intel MID Resistive Touch Screen Driver
4 * Copyright (C) 2008 Intel Corp
6 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; ifnot, write to the Free Software Foundation, Inc.,
19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21 * Questions/Comments/Bug fixes to Sreedhara (sreedhara.ds@intel.com)
22 * Ramesh Agarwal (ramesh.agarwal@intel.com)
23 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
26 * kill off mrstouch_debug eventually
27 * review conversion of r/m/w sequences
28 * Replace interrupt mutex abuse
29 * Kill of mrstouchdevp pointer
33 #include <linux/module.h>
34 #include <linux/init.h>
35 #include <linux/input.h>
36 #include <linux/interrupt.h>
37 #include <linux/err.h>
38 #include <linux/param.h>
39 #include <linux/spi/spi.h>
40 #include <linux/irq.h>
41 #include <linux/delay.h>
42 #include <linux/kthread.h>
43 #include <asm/intel_scu_ipc.h>
46 #if defined(MRSTOUCH_DEBUG)
47 #define mrstouch_debug(fmt, args...)\
49 printk(KERN_DEBUG "\n[MRSTOUCH(%d)] - ", __LINE__); \
50 printk(KERN_DEBUG fmt, ##args); \
53 #define mrstouch_debug(fmt, args...)
56 /* PMIC Interrupt registers */
57 #define PMIC_REG_ID1 0x00 /*PMIC ID1 register */
59 /* PMIC Interrupt registers */
60 #define PMIC_REG_INT 0x04 /*PMIC interrupt register */
61 #define PMIC_REG_MINT 0x05 /*PMIC interrupt mask register */
63 /* ADC Interrupt registers */
64 #define PMIC_REG_ADCINT 0x5F /*ADC interrupt register */
65 #define PMIC_REG_MADCINT 0x60 /*ADC interrupt mask register */
67 /* ADC Control registers */
68 #define PMIC_REG_ADCCNTL1 0x61 /*ADC control register */
70 /* ADC Channel Selection registers */
71 #define PMICADDR0 0xA4
72 #define END_OF_CHANNEL 0x1F
74 /* ADC Result register */
75 #define PMIC_REG_ADCSNS0H 0x64
77 /* ADC channels for touch screen */
78 #define MRST_TS_CHAN10 0xA /* Touch screen X+ connection */
79 #define MRST_TS_CHAN11 0xB /* Touch screen X- connection */
80 #define MRST_TS_CHAN12 0xC /* Touch screen Y+ connection */
81 #define MRST_TS_CHAN13 0xD /* Touch screen Y- connection */
83 /* Touch screen coordinate constants */
84 #define TOUCH_PRESSURE 50
85 #define TOUCH_PRESSURE_FS 100
91 #define MAX_10BIT ((1<<10)-1)
93 /* Touch screen channel BIAS constants */
98 /* Touch screen coordinates */
103 #define WAIT_ADC_COMPLETION 10
105 /* PMIC ADC round robin delays */
106 #define ADC_LOOP_DELAY0 0x0 /* Continuous loop */
107 #define ADC_LOOP_DELAY1 0x1 /* 4.5 ms approximate */
109 /* PMIC Vendor Identifiers */
110 #define PMIC_VENDOR_FS 0 /* PMIC vendor FreeScale */
111 #define PMIC_VENDOR_MAXIM 1 /* PMIC vendor MAXIM */
112 #define PMIC_VENDOR_NEC 2 /* PMIC vendor NEC */
113 #define MRSTOUCH_MAX_CHANNELS 32 /* Maximum ADC channels */
115 /* Touch screen device structure */
116 struct mrstouch_dev
{
117 struct spi_device
*spi
; /* SPI device associated with touch screen */
118 struct input_dev
*input
; /* input device for touchscreen*/
119 char phys
[32]; /* Device name */
120 struct task_struct
*pendet_thrd
; /* PENDET interrupt handler */
121 struct mutex lock
; /* Sync between interrupt and PENDET handler */
122 bool busy
; /* Busy flag */
123 u16 asr
; /* Address selection register */
124 int irq
; /* Touch screen IRQ # */
125 uint vendor
; /* PMIC vendor */
126 uint rev
; /* PMIC revision */
127 bool suspended
; /* Device suspended status */
128 bool disabled
; /* Device disabled status */
129 u16 x
; /* X coordinate */
130 u16 y
; /* Y coordinate */
131 bool pendown
; /* PEN position */
135 /* Global Pointer to Touch screen device */
136 static struct mrstouch_dev
*mrstouchdevp
;
138 /* Utility to read PMIC ID */
139 static int mrstouch_pmic_id(uint
*vendor
, uint
*rev
)
144 err
= intel_scu_ipc_ioread8(PMIC_REG_ID1
, &r
);
149 *rev
= (r
>> 3) & 0x7;
155 * Parse ADC channels to find end of the channel configured by other ADC user
156 * NEC and MAXIM requires 4 channels and FreeScale needs 18 channels
158 static int mrstouch_chan_parse(struct mrstouch_dev
*tsdev
)
160 int err
, i
, j
, found
;
165 for (i
= 0; i
< MRSTOUCH_MAX_CHANNELS
; i
++) {
169 err
= intel_scu_ipc_ioread32(PMICADDR0
, &r32
);
173 for (j
= 0; j
< 32; j
+= 8) {
174 if (((r32
>> j
) & 0xFF) == END_OF_CHANNEL
) {
183 if (tsdev
->vendor
== PMIC_VENDOR_FS
) {
184 if (found
&& found
> (MRSTOUCH_MAX_CHANNELS
- 18))
187 if (found
&& found
> (MRSTOUCH_MAX_CHANNELS
- 4))
193 /* Utility to enable/disable pendet.
194 * pendet set to true enables PENDET interrupt
195 * pendet set to false disables PENDET interrupt
196 * Also clears RND mask bit
198 static int pendet_enable(struct mrstouch_dev
*tsdev
, bool pendet
)
202 u8 pendet_enabled
= 0;
206 err
= intel_scu_ipc_ioread16(PMIC_REG_MADCINT
, ®
);
212 reg
|= 0x2000; /* Enable pendet */
214 reg
&= 0xDFFF; /* Disable pendet */
216 /* Set MADCINT and update ADCCNTL1 (next reg byte) */
217 err
= intel_scu_ipc_iowrite16(PMIC_REG_MADCINT
, reg
);
222 * Sometimes even after the register write succeeds
223 * the PMIC register value is not updated. Retry few iterations
227 err
= intel_scu_ipc_ioread8(PMIC_REG_ADCCNTL1
, &r
);
228 pendet_enabled
= (r
>> 5) & 0x01;
231 while (!err
&& !pendet_enabled
) {
234 err
= intel_scu_ipc_iowrite8(PMIC_REG_ADCCNTL1
, reg
>> 8);
237 err
= intel_scu_ipc_ioread8(PMIC_REG_ADCCNTL1
, &r
);
239 pendet_enabled
= (r
>> 5) & 0x01;
241 dev_err(&tsdev
->spi
->dev
, "Touch screen disabled.\n");
248 /* To read PMIC ADC touch screen result
249 * Reads ADC storage registers for higher 7 and lower 3 bits
250 * converts the two readings to single value and turns off gain bit
252 static int mrstouch_ts_chan_read(u16 offset
, u16 chan
, u16
*vp
, u16
*vm
)
258 result
= PMIC_REG_ADCSNS0H
+ offset
;
260 if (chan
== MRST_TS_CHAN12
)
263 err
= intel_scu_ipc_ioread32(result
, &res
);
267 /* Mash the bits up */
269 *vp
= (res
& 0xFF) << 3; /* Highest 7 bits */
270 *vp
|= (res
>> 8) & 0x07; /* Lower 3 bits */
275 *vm
= (res
& 0xFF) << 3; /* Highest 7 bits */
276 *vm
|= (res
>> 8) & 0x07; /* Lower 3 bits */
282 /* To configure touch screen channels
283 * Writes touch screen channels to ADC address selection registers
285 static int mrstouch_ts_chan_set(uint offset
)
292 chan
= PMICADDR0
+ offset
;
293 for (count
= 0; count
<= 3; count
++) {
295 data
[count
] = MRST_TS_CHAN10
+ count
;
298 data
[count
] = END_OF_CHANNEL
;
300 return intel_scu_ipc_writev(reg
, data
, 5);
304 static int mrstouch_adc_init(struct mrstouch_dev
*tsdev
)
309 err
= mrstouch_pmic_id(&tsdev
->vendor
, &tsdev
->rev
);
311 dev_err(&tsdev
->spi
->dev
, "Unable to read PMIC id\n");
315 start
= mrstouch_chan_parse(tsdev
);
317 dev_err(&tsdev
->spi
->dev
, "Unable to parse channels\n");
323 mrstouch_debug("Channel offset(%d): 0x%X\n", tsdev
->asr
, tsdev
->vendor
);
325 /* ADC power on, start, enable PENDET and set loop delay
326 * ADC loop delay is set to 4.5 ms approximately
327 * Loop delay more than this results in jitter in adc readings
328 * Setting loop delay to 0 (continous loop) in MAXIM stops PENDET
329 * interrupt generation sometimes.
332 if (tsdev
->vendor
== PMIC_VENDOR_FS
) {
333 ra
= 0xE0 | ADC_LOOP_DELAY0
;
336 /* NEC and MAXIm not consistent with loop delay 0 */
337 ra
= 0xE0 | ADC_LOOP_DELAY1
;
340 /* configure touch screen channels */
341 err
= mrstouch_ts_chan_set(tsdev
->asr
);
345 err
= intel_scu_ipc_update_register(PMIC_REG_ADCCNTL1
, ra
, 0xE7);
347 err
= intel_scu_ipc_update_register(PMIC_REG_MADCINT
, rm
, 0x03);
351 /* Reports x,y coordinates to event subsystem */
352 static void mrstouch_report_xy(struct mrstouch_dev
*tsdev
, u16 x
, u16 y
, u16 z
)
356 if (tsdev
->pendown
&& z
<= TOUCH_PRESSURE
) {
357 /* Pen removed, report button release */
358 mrstouch_debug("BTN REL(%d)", z
);
359 input_report_key(tsdev
->input
, BTN_TOUCH
, 0);
360 tsdev
->pendown
= false;
363 xdiff
= abs(x
- tsdev
->x
);
364 ydiff
= abs(y
- tsdev
->y
);
367 if x and y values changes for XYMOVE_CNT readings it is considered
368 as stylus is moving. This is required to differentiate between stylus
371 if (x
< MIN_X
|| x
> MAX_X
|| y
< MIN_Y
|| y
> MAX_Y
) {
372 /* Spurious values, release button if touched and return */
373 if (tsdev
->pendown
) {
374 mrstouch_debug("BTN REL(%d)", z
);
375 input_report_key(tsdev
->input
, BTN_TOUCH
, 0);
376 tsdev
->pendown
= false;
379 } else if (xdiff
>= XMOVE_LIMIT
|| ydiff
>= YMOVE_LIMIT
) {
383 input_report_abs(tsdev
->input
, ABS_X
, x
);
384 input_report_abs(tsdev
->input
, ABS_Y
, y
);
385 input_sync(tsdev
->input
);
389 if (!tsdev
->pendown
&& z
> TOUCH_PRESSURE
) {
390 /* Pen touched, report button touch */
391 mrstouch_debug("BTN TCH(%d, %d, %d)", x
, y
, z
);
392 input_report_key(tsdev
->input
, BTN_TOUCH
, 1);
393 tsdev
->pendown
= true;
398 /* Utility to start ADC, used by freescale handler */
399 static int pendet_mask(void)
401 return intel_scu_ipc_update_register(PMIC_REG_MADCINT
, 0x02, 0x02);
404 /* Utility to stop ADC, used by freescale handler */
405 static int pendet_umask(void)
407 return intel_scu_ipc_update_register(PMIC_REG_MADCINT
, 0x00, 0x02);
410 /* Utility to read ADC, used by freescale handler */
411 static int mrstouch_pmic_fs_adc_read(struct mrstouch_dev
*tsdev
)
418 result
= PMIC_REG_ADCSNS0H
+ tsdev
->asr
;
422 reg
[2] = result
+ 16;
423 reg
[3] = result
+ 17;
425 err
= intel_scu_ipc_readv(reg
, data
, 4);
429 x
= data
[0] << 3; /* Higher 7 bits */
430 x
|= data
[1] & 0x7; /* Lower 3 bits */
433 y
= data
[2] << 3; /* Higher 7 bits */
434 y
|= data
[3] & 0x7; /* Lower 3 bits */
438 reg
[0] = result
+ 28;
439 reg
[1] = result
+ 29;
441 err
= intel_scu_ipc_readv(reg
, data
, 4);
445 z
= data
[0] << 3; /* Higher 7 bits */
446 z
|= data
[1] & 0x7; /* Lower 3 bits */
449 #if defined(MRSTOUCH_PRINT_XYZP)
450 mrstouch_debug("X: %d, Y: %d, Z: %d", x
, y
, z
);
453 if (z
>= TOUCH_PRESSURE_FS
) {
454 mrstouch_report_xy(tsdev
, x
, y
, TOUCH_PRESSURE
- 1); /* Pen Removed */
455 return TOUCH_PRESSURE
- 1;
457 mrstouch_report_xy(tsdev
, x
, y
, TOUCH_PRESSURE
+ 1); /* Pen Touched */
458 return TOUCH_PRESSURE
+ 1;
464 dev_err(&tsdev
->spi
->dev
, "ipc error during fs_adc read\n");
468 /* To handle free scale pmic pendet interrupt */
469 static int pmic0_pendet(void *dev_id
)
473 unsigned int touched
;
474 struct mrstouch_dev
*tsdev
= (struct mrstouch_dev
*)dev_id
;
478 chan
= PMICADDR0
+ tsdev
->asr
;
481 for (count
= 0; count
<= 3; count
++) {
485 reg
[count
] = chan
++; /* Dummy */
488 err
= intel_scu_ipc_writev(reg
, data
, 5);
492 msleep(WAIT_ADC_COMPLETION
);
495 for (count
= 0; count
<= 3; count
++) {
499 reg
[count
] = chan
++; /* Dummy */
502 err
= intel_scu_ipc_writev(reg
, data
, 5);
506 msleep(WAIT_ADC_COMPLETION
);
509 err
= intel_scu_ipc_iowrite32(chan
+ 2, 0x8A8A8A8A);
513 msleep(WAIT_ADC_COMPLETION
);
515 /*Read touch screen channels till pen removed
516 * Freescale reports constant value of z for all points
517 * z is high when screen is not touched and low when touched
518 * Map high z value to not touched and low z value to pen touched
520 touched
= mrstouch_pmic_fs_adc_read(tsdev
);
521 while (touched
> TOUCH_PRESSURE
) {
522 touched
= mrstouch_pmic_fs_adc_read(tsdev
);
523 msleep(WAIT_ADC_COMPLETION
);
526 /* Clear all TS channels */
527 chan
= PMICADDR0
+ tsdev
->asr
;
528 for (count
= 0; count
<= 4; count
++) {
532 err
= intel_scu_ipc_writev(reg
, data
, 5);
536 for (count
= 0; count
<= 4; count
++) {
540 err
= intel_scu_ipc_writev(reg
, data
, 5);
544 err
= intel_scu_ipc_iowrite32(chan
+ 2, 0x00000000);
551 dev_err(&tsdev
->spi
->dev
, "ipc error during pendet\n");
556 /* To enable X, Y and Z bias values
557 * Enables YPYM for X channels and XPXM for Y channels
559 static int mrstouch_ts_bias_set(uint offset
, uint bias
)
566 chan
= PMICADDR0
+ offset
;
567 start
= MRST_TS_CHAN10
;
569 for (count
= 0; count
<= 3; count
++) {
571 data
[count
] = bias
| (start
+ count
);
573 return intel_scu_ipc_writev(reg
, data
, 4);
576 /* To read touch screen channel values */
577 static int mrstouch_adc_read(struct mrstouch_dev
*tsdev
)
580 u16 xp
, xm
, yp
, ym
, zp
, zm
;
582 /* configure Y bias for X channels */
583 err
= mrstouch_ts_bias_set(tsdev
->asr
, YBIAS
);
587 msleep(WAIT_ADC_COMPLETION
);
589 /* read x+ and x- channels */
590 err
= mrstouch_ts_chan_read(tsdev
->asr
, MRST_TS_CHAN10
, &xp
, &xm
);
594 /* configure x bias for y channels */
595 err
= mrstouch_ts_bias_set(tsdev
->asr
, XBIAS
);
599 msleep(WAIT_ADC_COMPLETION
);
601 /* read y+ and y- channels */
602 err
= mrstouch_ts_chan_read(tsdev
->asr
, MRST_TS_CHAN12
, &yp
, &ym
);
606 /* configure z bias for x and y channels */
607 err
= mrstouch_ts_bias_set(tsdev
->asr
, ZBIAS
);
611 msleep(WAIT_ADC_COMPLETION
);
613 /* read z+ and z- channels */
614 err
= mrstouch_ts_chan_read(tsdev
->asr
, MRST_TS_CHAN10
, &zp
, &zm
);
618 #if defined(MRSTOUCH_PRINT_XYZP)
619 printk(KERN_INFO
"X+: %d, Y+: %d, Z+: %d\n", xp
, yp
, zp
);
622 #if defined(MRSTOUCH_PRINT_XYZM)
623 printk(KERN_INFO
"X-: %d, Y-: %d, Z-: %d\n", xm
, ym
, zm
);
626 mrstouch_report_xy(tsdev
, xp
, yp
, zp
); /* report x and y to eventX */
631 dev_err(&tsdev
->spi
->dev
, "ipc error during adc read\n");
635 /* PENDET interrupt handler function for NEC and MAXIM */
636 static void pmic12_pendet(void *data
)
638 unsigned int touched
;
639 struct mrstouch_dev
*tsdev
= (struct mrstouch_dev
*)data
;
641 /* read touch screen channels till pen removed */
643 touched
= mrstouch_adc_read(tsdev
);
644 } while (touched
> TOUCH_PRESSURE
);
647 /* Handler to process PENDET interrupt */
648 int mrstouch_pendet(void *data
)
650 struct mrstouch_dev
*tsdev
= (struct mrstouch_dev
*)data
;
652 /* Wait for PENDET interrupt */
653 if (mutex_lock_interruptible(&tsdev
->lock
)) {
654 msleep(WAIT_ADC_COMPLETION
);
663 if (tsdev
->vendor
== PMIC_VENDOR_NEC
||
664 tsdev
->vendor
== PMIC_VENDOR_MAXIM
) {
665 /* PENDET must be disabled in NEC before reading ADC */
666 pendet_enable(tsdev
,false); /* Disbale PENDET */
667 pmic12_pendet(tsdev
);
668 pendet_enable(tsdev
, true); /*Enable PENDET */
669 } else if (tsdev
->vendor
== PMIC_VENDOR_FS
) {
670 pendet_umask(); /* Stop ADC */
672 pendet_mask(); /* Stop ADC */
674 dev_err(&tsdev
->spi
->dev
, "Unsupported touchscreen: %d\n",
683 /* PENDET interrupt handler */
684 static irqreturn_t
pendet_intr_handler(int irq
, void *handle
)
686 struct mrstouch_dev
*tsdev
= (struct mrstouch_dev
*)handle
;
688 mutex_unlock(&tsdev
->lock
);
692 /* Intializes input device and registers with input subsystem */
693 static int ts_input_dev_init(struct mrstouch_dev
*tsdev
, struct spi_device
*spi
)
697 mrstouch_debug("%s", __func__
);
699 tsdev
->input
= input_allocate_device();
701 dev_err(&tsdev
->spi
->dev
, "Unable to allocate input device.\n");
705 tsdev
->input
->name
= "mrst_touchscreen";
706 snprintf(tsdev
->phys
, sizeof(tsdev
->phys
),
707 "%s/input0", dev_name(&spi
->dev
));
708 tsdev
->input
->phys
= tsdev
->phys
;
709 tsdev
->input
->dev
.parent
= &spi
->dev
;
711 tsdev
->input
->id
.vendor
= tsdev
->vendor
;
712 tsdev
->input
->id
.version
= tsdev
->rev
;
714 tsdev
->input
->evbit
[0] = BIT_MASK(EV_KEY
) | BIT_MASK(EV_ABS
);
715 tsdev
->input
->keybit
[BIT_WORD(BTN_TOUCH
)] = BIT_MASK(BTN_TOUCH
);
717 input_set_abs_params(tsdev
->input
, ABS_X
, MIN_X
, MIN_Y
, 0, 0);
718 input_set_abs_params(tsdev
->input
, ABS_Y
, MIN_X
, MIN_Y
, 0, 0);
720 err
= input_register_device(tsdev
->input
);
722 dev_err(&tsdev
->spi
->dev
, "unable to register input device\n");
723 input_free_device(tsdev
->input
);
727 mrstouch_debug("%s", "mrstouch initialized");
733 /* Probe function for touch screen driver */
734 static int __devinit
mrstouch_probe(struct spi_device
*mrstouch_spi
)
738 struct mrstouch_dev
*tsdev
;
740 mrstouch_debug("%s(%p)", __func__
, mrstouch_spi
);
743 myirq
= mrstouch_spi
->irq
;
745 if (!mrstouch_spi
->irq
) {
746 dev_err(&mrstouch_spi
->dev
, "no interrupt assigned\n");
750 tsdev
= kzalloc(sizeof(struct mrstouch_dev
), GFP_KERNEL
);
752 dev_err(&mrstouch_spi
->dev
, "unable to allocate memory\n");
757 mrstouchdevp
= tsdev
;
759 err
= mrstouch_adc_init(tsdev
);
761 dev_err(&mrstouch_spi
->dev
, "ADC init failed\n");
762 goto mrstouch_err_free_mem
;
765 dev_set_drvdata(&mrstouch_spi
->dev
, tsdev
);
766 tsdev
->spi
= mrstouch_spi
;
768 err
= ts_input_dev_init(tsdev
, mrstouch_spi
);
770 dev_err(&tsdev
->spi
->dev
, "ts_input_dev_init failed");
771 goto mrstouch_err_free_mem
;
774 mutex_init(&tsdev
->lock
);
775 mutex_lock(&tsdev
->lock
)
777 mrstouch_debug("Requesting IRQ-%d", myirq
);
778 err
= request_irq(myirq
, pendet_intr_handler
,
779 0, "mrstouch", tsdev
);
781 dev_err(&tsdev
->spi
->dev
, "unable to allocate irq\n");
782 goto mrstouch_err_free_mem
;
785 tsdev
->pendet_thrd
= kthread_run(mrstouch_pendet
,
786 (void *)tsdev
, "pendet handler");
787 if (IS_ERR(tsdev
->pendet_thrd
)) {
788 dev_err(&tsdev
->spi
->dev
, "kthread_run failed\n");
789 err
= PTR_ERR(tsdev
->pendet_thrd
);
790 goto mrstouch_err_free_mem
;
792 mrstouch_debug("%s", "Driver initialized");
795 mrstouch_err_free_mem
:
800 static int mrstouch_suspend(struct spi_device
*spi
, pm_message_t msg
)
802 mrstouch_debug("%s", __func__
);
803 mrstouchdevp
->suspended
= 1;
807 static int mrstouch_resume(struct spi_device
*spi
)
809 mrstouch_debug("%s", __func__
);
810 mrstouchdevp
->suspended
= 0;
814 static int mrstouch_remove(struct spi_device
*spi
)
816 mrstouch_debug("%s", __func__
);
817 free_irq(mrstouchdevp
->irq
, mrstouchdevp
);
818 input_unregister_device(mrstouchdevp
->input
);
819 input_free_device(mrstouchdevp
->input
);
821 if (mrstouchdevp
->pendet_thrd
)
822 kthread_stop(mrstouchdevp
->pendet_thrd
);
826 static struct spi_driver mrstouch_driver
= {
828 .name
= "pmic_touch",
829 .bus
= &spi_bus_type
,
830 .owner
= THIS_MODULE
,
832 .probe
= mrstouch_probe
,
833 .suspend
= mrstouch_suspend
,
834 .resume
= mrstouch_resume
,
835 .remove
= mrstouch_remove
,
838 static int __init
mrstouch_module_init(void)
842 mrstouch_debug("%s", __func__
);
843 err
= spi_register_driver(&mrstouch_driver
);
845 mrstouch_debug("%s(%d)", "SPI PENDET failed", err
);
852 static void __exit
mrstouch_module_exit(void)
854 mrstouch_debug("%s", __func__
);
855 spi_unregister_driver(&mrstouch_driver
);
859 module_init(mrstouch_module_init
);
860 module_exit(mrstouch_module_exit
);
862 MODULE_AUTHOR("Sreedhara Murthy. D.S, sreedhara.ds@intel.com");
863 MODULE_DESCRIPTION("Intel Moorestown Resistive Touch Screen Driver");
864 MODULE_LICENSE("GPL");