]> rtime.felk.cvut.cz Git - mx1ts.git/blob - mx1_ts-driver.c
odebrany staticke promene posledni polohy. Posledni poloha patri do struktury mx1ts
[mx1ts.git] / mx1_ts-driver.c
1 /*
2  * MX1 touchscreen driver
3  *
4  * Copyright (C) 2008
5  * Radek Pupak (pupakr1@fel.cvut.cz)
6  * Czech Technical University, FEE, DCE
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  *
12  * This code is heavily based on ucb*.c copyrighted by Russell King
13  * and Nicolas Pitre covering the UCB1100, UCB1200, UCB1300 and UCB1400.
14  *
15  * Hardware specific properties are based on mx1ts.h and mx1ts.c copyrated
16  * by Blue Mug, Inc. for Motorola, Inc.
17  *
18  */
19
20
21 #include <linux/module.h>
22 #include <linux/moduleparam.h>
23 #include <linux/init.h>
24 #include <linux/completion.h>
25 #include <linux/delay.h>
26 #include <linux/input.h>
27 #include <linux/device.h>
28 #include <linux/interrupt.h>
29 #include <linux/suspend.h>
30 #include <linux/slab.h>
31 #include <linux/kthread.h>
32 #include <linux/freezer.h>
33 #include <linux/io.h>
34
35 #include <sound/driver.h>
36 #include <sound/core.h>
37 #include <sound/ac97_codec.h>
38
39 #include <linux/gameport.h>             //bonus XXX
40
41 #include <linux/platform_device.h>
42
43
44
45 /*
46  * originaly from
47  * linux/drivers/misc/mx1ts.h
48  *
49  * Copyright (C) 2003 Blue Mug, Inc. for Motorola, Inc.
50  *
51  * This program is free software; you can redistribute it and/or modify
52  * it under the terms of the GNU General Public License version 2 as
53  * published by the Free Software Foundation.
54  *
55  */
56
57 /* Interrupt numbers */
58 #define ASP_COMPARE_IRQ         5
59 #define ASP_PENDATA_IRQ         33
60 #define ASP_TOUCH_IRQ           46
61
62 /* Analog signal processor (ASP) control registers */
63 #define ASP_BASE_ADDR           0x00215000
64
65 #define ASP_ACNTLCR             (0x10)     /* Control register */
66 #define ASP_PSMPLRG             (0x14)     /* Pen A/D sampe rate control */
67 #define ASP_CMPCNTL             (0x30)     /* Compare control register */
68 #define ASP_ICNTLR              (0x18)     /* Interrupt control register */
69 #define ASP_ISTATR              (0x1C)     /* Interrupt status register */
70 #define ASP_PADFIFO             (0x00)     /* Pen sample FIFO */
71 #define ASP_CLKDIV              (0x2C)     /* Clock divide register */
72
73 /* ASP control register bits */
74 #define ASP_CLKEN               (1 << 25)       /* Clock enable */
75 #define ASP_SWRST               (1 << 23)       /* Software reset */
76 #define ASP_U_SEL               (1 << 21)       /* U-channel resistor select */
77 #define ASP_AZ_SEL              (1 << 20)       /* Auto-zero position select */
78 #define ASP_LVM                 (1 << 19)       /* Low voltage output */
79 #define ASP_NM                  (1 << 18)       /* Normal voltage output */
80 #define ASP_HPM                 (1 << 17)       /* High voltage output */
81 #define ASP_GLO                 (1 << 16)       /* Low gain enable */
82 #define ASP_AZE                 (1 << 15)       /* Auto-zero enable */
83 #define ASP_AUTO                (1 << 14)       /* Auto sampling */
84 #define ASP_SW8                 (1 << 11)       /* Switch control 8 */
85 #define ASP_SW7                 (1 << 10)
86 #define ASP_SW6                 (1 << 9)
87 #define ASP_SW5                 (1 << 8)
88 #define ASP_SW4                 (1 << 7)
89 #define ASP_SW3                 (1 << 6)
90 #define ASP_SW2                 (1 << 5)
91 #define ASP_SW1                 (1 << 4)        /* Switch control 1 */
92 #define ASP_VDAE                (1 << 3)        /* Voice D/A enable */
93 #define ASP_VADE                (1 << 2)        /* Voice A/D enable */
94 #define ASP_PADE                (1 << 1)        /* Pen A/D enable */
95 #define ASP_BGE                 (1 << 0)        /* Bandgap enable */
96
97 #define ASP_MODE_MASK           0x00003000
98 #define ASP_MODE_NONE           0x00000000
99 #define ASP_MODE_ONLY_X         0x00001000
100 #define ASP_MODE_ONLY_Y         0x00002000
101 #define ASP_MODE_ONLY_U         0x00003000
102
103 /* ASP Pen A/D sample rate control register */
104 #define ASP_DMCNT_MASK          (0x00007000)    /* Decimation ratio count */
105 #define ASP_DMCNT_SCALE         (12)
106 #define ASP_BIT_SELECT_MASK     (0x00000C00)    /* Bit select */
107 #define ASP_BIT_SELECT_SCALE    (10)
108 #define ASP_IDLECNT_MASK        (0x000003F0)    /* Idle count */
109 #define ASP_IDLECNT_SCALE       (4)
110 #define ASP_DSCNT_MASK          (0x0000000F)    /* Data setup count */
111 #define ASP_DSCNT_SCALE         (0)
112
113 /* ASP compare control register */
114 #define ASP_INT                 (1 << 19)       /* Interrupt status */
115 #define ASP_CC                  (1 << 18)       /* Trigger on greater than */
116 #define ASP_INSEL_MASK          (0x00030000)
117 #define ASP_INSEL_DISABLE       (0x00000000)
118 #define ASP_INSEL_X             (0x00010000)
119 #define ASP_INSEL_Y             (0x00020000)
120 #define ASP_INSEL_U             (0x00030000)
121 #define ASP_COMPARE_VAL_MASK    (0x0000FFFF)
122 #define ASP_COMPARE_VAL_SCALE   (0)
123
124 /* ASP interrupt control register bits */
125 #define ASP_PUIE                (1 << 10)       /* Pen up XXX undocumented */
126 #define ASP_VDDMAE              (1 << 8)        /* VDAC FIFO empty DMA */
127 #define ASP_VADMAE              (1 << 7)        /* VADC FIFO full DMA */
128 #define ASP_POL                 (1 << 6)        /* Pen interrupt polarity */
129 #define ASP_EDGE                (1 << 5)        /* Edge trigger enable */
130 #define ASP_PIRQE               (1 << 4)        /* Pen interrupt enable */
131 #define ASP_VDAFEE              (1 << 3)        /* VDAC FIFO empty interrupt */
132 #define ASP_VADFFE              (1 << 2)        /* VADC FIFO full interrupt */
133 #define ASP_PFFE                (1 << 1)        /* Pen FIFO full interrupt */
134 #define ASP_PDRE                (1 << 0)        /* Pen data ready interrupt */
135
136 /* ASP interrupt/error status register bits */
137 #define ASP_PUIS                 (1 << 10)       /* Pen-up Status,event-> clear by 1 */
138 #define ASP_BGR                 (1 << 9)        /* Bandgap ready */
139 #define ASP_VOV                 (1 << 8)        /* Voice sample data overflow */
140 #define ASP_POV                 (1 << 7)        /* Pen sample data overflow */
141 #define ASP_PEN                 (1 << 6)        /* Pen interrupt */
142 #define ASP_VDAFF               (1 << 5)        /* VDAC FIFO full */
143 #define ASP_VDAFE               (1 << 4)        /* VDAC FIFO empty */
144 #define ASP_VADFF               (1 << 3)        /* VADC FIFO full */
145 #define ASP_VADDR               (1 << 2)        /* VADC data ready */
146 #define ASP_PFF                 (1 << 1)        /* Pen sample FIFO full */
147 #define ASP_PDR                 (1 << 0)        /* Pen data ready */
148
149 /* ASP Clock divide register */
150 #define ASP_PADC_CLK_MASK       (0x0000001F)
151 #define ASP_PADC_CLK_SCALE      (0)
152 #define ASP_VADC_CLK_MASK       (0x000003E0)
153 #define ASP_VADC_CLK_SCALE      (5)
154 #define ASP_VDAC_CLK_MASK       (0x00003C00)
155 #define ASP_VDAC_CLK_SCALE      (10)
156
157 #define DEV_IRQ_ID      "mx1-ts"
158
159 struct mx1ts {
160         struct input_dev        *ts_idev;
161         struct resource         pamet;
162         int                     irq;
163
164         wait_queue_head_t       ts_wait;
165         struct task_struct      *ts_task;
166
167         unsigned int            irq_pending;    
168         unsigned int            ts_restart:1;
169         unsigned int            adcsync:1;
170         void __iomem*           mx1ts_mem;
171         
172         u16                     x_res;          
173         u16                     y_res;
174         u16                     x_akt;
175         u16                     y_akt;
176         u16                     u_akt;
177         u16                     cal_auto_zero;
178         u16                     cal_range_x;
179         u16                     cal_range_y;
180         unsigned int            stav;
181         u8                      auto_calibration;
182         u8                      is_open;
183
184 }; 
185
186
187 static inline void mx1ts_reg_set_mask(struct mx1ts *mts , unsigned int reg, u32 mask)
188 {       
189         u32 val;
190         val = __raw_readl(mts->mx1ts_mem+reg);
191         val |= mask;
192         __raw_writel(val, mts->mx1ts_mem+reg );
193 }
194
195 static inline void mx1ts_reg_clear_mask(struct mx1ts *mts , unsigned int reg, u32 mask)
196 {       
197         u32 val;
198         val = __raw_readl(mts->mx1ts_mem+reg);
199         val &= mask;
200         __raw_writel(val, mts->mx1ts_mem+reg );
201 }
202
203 static inline void mx1ts_reg_write(struct mx1ts *mts, unsigned int reg, unsigned int val)
204 {       
205         __raw_writel(val, mts->mx1ts_mem+reg);
206         printk(KERN_DEBUG "mx1_touchscreen: writing into : %p value %x\n",mts->mx1ts_mem+reg, val);
207         
208 }
209
210 static inline unsigned int mx1ts_reg_read(struct mx1ts *mts, unsigned int reg)
211 {
212         unsigned int out;
213
214         out =  __raw_readl( mts->mx1ts_mem + reg );     
215         /*printk(KERN_DEBUG "mx1_touchscreen: reading from %p : %d \n",mts->mx1ts_mem + reg, out);*/
216                 
217         return out;
218 }
219
220 static inline void mx1ts_flush_fifo(struct mx1ts *mts)
221 {
222         int i;
223         for (i = 0; i < 12; i++)
224                 if (mx1ts_reg_read(mts, ASP_ISTATR) & (ASP_PFF | ASP_PDR))
225                         mx1ts_reg_read(mts, ASP_PADFIFO);
226 }
227
228 static void mx1ts_enable_auto_sample(struct mx1ts *mts)
229 {
230         unsigned int value;
231
232         mx1ts_flush_fifo(mts);
233
234         value = mx1ts_reg_read(mts, ASP_ACNTLCR);
235
236         /* Set the mode to X then Y */
237         value &= ~ASP_MODE_MASK;
238         value |= ASP_MODE_ONLY_Y;
239
240         /* Enable auto zero. */
241         value |= ASP_AZE;
242
243         /* Enable auto sample. */
244         value |= ASP_AUTO;
245
246         /* Enable pen A/D. */
247         value |= ASP_PADE;
248         mx1ts_reg_write(mts, ASP_ACNTLCR, value);
249
250         /* Enable pen data ready and full interrupt. */
251         value = mx1ts_reg_read(mts, ASP_ICNTLR);
252         value |= ASP_PFFE | ASP_PDRE;
253         mx1ts_reg_write(mts, ASP_ICNTLR, value);
254 }
255
256
257 static void mx1ts_disable_auto_sample(struct mx1ts *mts)
258 {
259         unsigned int value;
260
261         value = mx1ts_reg_read(mts, ASP_ACNTLCR);
262
263         /* Set the mode to none */
264         value &= ~ASP_MODE_MASK;
265
266         /* Disable auto zero. */
267         value &= ~ASP_AZE;
268
269         /* Disable auto sample. */
270         value &= ~ASP_AUTO;
271
272         /* Disable pen A/D. */
273         value &= ~ASP_PADE;
274         mx1ts_reg_write(mts, ASP_ACNTLCR, value);
275
276         /* Disable pen data ready and full interrupt. */
277         value = mx1ts_reg_read(mts, ASP_ICNTLR);
278         value &= ~(ASP_PFFE | ASP_PDRE);
279         mx1ts_reg_write(mts, ASP_ICNTLR, value);
280 }
281
282 static void mx1ts_enable_pen_touch_interrupt(struct mx1ts *mts)
283 {
284         unsigned int value;
285
286         /* Enable pen touch interrupt. */
287         value = mx1ts_reg_read(mts, ASP_ICNTLR);
288         value |= ASP_EDGE | /*ASP_POL |*/ ASP_PIRQE;
289         mx1ts_reg_write(mts, ASP_ICNTLR, value);
290         
291         printk(KERN_DEBUG "mx1_touchscreen: pen_touch: activating pen_down interrupt \n");
292 }
293
294 static void mx1ts_disable_pen_touch_interrupt(struct mx1ts *mts)
295 {
296         unsigned int value;
297
298         /* Enable pen touch interrupt. */
299         value = mx1ts_reg_read(mts, ASP_ICNTLR);
300         value &= ~ASP_PIRQE;
301         mx1ts_reg_write(mts, ASP_ICNTLR, value);
302         printk(KERN_DEBUG "mx1_touchscreen: pen_touch: deaktivating pen_down interrupt \n");
303 }
304
305 static void mx1ts_enable_pen_up_interrupt(struct mx1ts *mts)
306 {
307         unsigned int value;
308
309         value = mx1ts_reg_read(mts, ASP_ICNTLR);
310         value |= ASP_PUIE; 
311         mx1ts_reg_write(mts, ASP_ICNTLR, value);
312         printk(KERN_DEBUG "mx1_touchscreen: pen_up: activating pen_up interrupt \n");
313 }
314
315 static void mx1ts_disable_pen_up_interrupt(struct mx1ts *mts)
316 {
317         unsigned int value;
318
319         /* Enable pen up interrupt.  */
320         value = mx1ts_reg_read(mts, ASP_ICNTLR);
321         value &= ~ASP_PUIE;
322         mx1ts_reg_write(mts, ASP_ICNTLR, value);
323         printk(KERN_DEBUG "mx1_touchscreen: pen_up: deaktivating pen_up interrupt \n");
324 }
325
326
327
328 static void mx1ts_start_auto_calibration(struct mx1ts *mts)
329 {
330         unsigned int value;
331         printk(KERN_DEBUG "mx1_touchscreen: start_auto_calibration \n");
332
333
334         mts->auto_calibration = 1;
335
336         value = mx1ts_reg_read(mts, ASP_ACNTLCR);
337
338         /* Set the mode to X then Y */
339         value &= ~ASP_MODE_MASK;
340         value |= ASP_MODE_ONLY_X;
341
342         /* Enable auto zero. */
343         value |= ASP_AZE;
344
345         /* Enable auto calibrate. XXX: Undocumented bitfield. */
346         value |= 0x04000000;
347
348         /* Enable auto sample. */
349         value |= ASP_AUTO;
350
351         /* Enable pen A/D. */
352         value |= ASP_PADE;
353         mx1ts_reg_write(mts, ASP_ACNTLCR, value);
354
355         /* Enable pen data ready and full interrupt. */
356         value = mx1ts_reg_read(mts, ASP_ICNTLR);
357         value |= ASP_PFFE | ASP_PDRE | ASP_PUIE;
358         mx1ts_reg_write(mts, ASP_ICNTLR, value);
359 }
360
361 static void mx1ts_reset_asp(struct mx1ts *mts)
362 {
363         unsigned int value;
364
365         mx1ts_flush_fifo(mts);
366
367         /* Soft reset the ASP module */
368         mx1ts_reg_write(mts, ASP_ACNTLCR, ASP_SWRST);
369         /* Read back the reset value of the control register */
370         value = mx1ts_reg_read(mts, ASP_ACNTLCR);
371
372         /* Enable the clock and wait for a short while */
373         value |= ASP_CLKEN;
374         mx1ts_reg_write(mts, ASP_ACNTLCR, value);
375         udelay(100);
376
377         /* Set the value of the conrtol register. */
378         value = ASP_CLKEN | ASP_NM | ASP_SW6 | ASP_BGE;
379         mx1ts_reg_write(mts, ASP_ACNTLCR, value);
380
381         /* 0x01 Set the clock divide ratio to 2. */
382         mx1ts_reg_write(mts, ASP_CLKDIV, 0x1f);
383
384         /* Set the sample rate control register. These values should yield
385          * about 150 samples per second, which seems to give good smooth
386          * lines. */
387         value = (0x7 << ASP_DMCNT_SCALE) |      /* 0x2 - Decimation ratio is 3 */
388                 (0x3F << ASP_IDLECNT_SCALE) |   /* 0x1 - Idle count is 1 clock */
389                 (0xF << ASP_DSCNT_SCALE);       /* 0x2 - Data setup is 2 clocks */
390         mx1ts_reg_write(mts, ASP_PSMPLRG, value);
391
392         /* Disable the compare function. */
393         mx1ts_reg_write(mts, ASP_CMPCNTL, 0);
394 }
395
396 static void mx1ts_evt_add_touch(struct input_dev *idev, u8 p , u16 x, u16 y)
397 {
398         struct mx1ts *mts = dev_get_drvdata(idev->dev.parent);
399         mts->x_akt = x;
400         mts->y_akt = y;
401
402         input_report_key(idev, BTN_TOUCH, 1);
403         input_report_abs(idev, ABS_X, x);
404         input_report_abs(idev, ABS_Y, y);
405         /*input_report_abs(idev, ABS_PRESSURE, p);*/
406         input_report_abs(idev, ABS_PRESSURE, 1);
407         input_sync(idev);
408 }
409
410 static void mx1ts_evt_add_up(struct input_dev *idev)
411 {
412         struct mx1ts *mts = dev_get_drvdata(idev->dev.parent);
413         
414         input_report_abs(idev, ABS_X, mts->x_akt);
415         input_report_abs(idev, ABS_Y, mts->y_akt);
416         input_report_abs(idev, ABS_PRESSURE, 0);
417         /*input_report_key(idev, BTN_TOUCH, 0);*/
418         input_sync(idev);
419 }
420
421 /*
422  * Handle the pen data ready interrupt, generated when pen data is
423  * in the FIFO.
424  */
425
426 static irqreturn_t mx1ts_pendata_irq(int irq, void *dev_id)
427 {       
428         
429         struct mx1ts *mts = (struct mx1ts *)dev_id;
430         u16 mx1_cal_range_x;
431         u16 mx1_cal_range_y;
432         static unsigned int auto_zero, pen_x, pen_y, pen_u;
433
434         mx1_cal_range_x = 1;
435         mx1_cal_range_y = 1;
436
437         /*printk(KERN_DEBUG "mx1_touchscreen mx1ts_pendata_irq \n");*/
438 /*      printk(KERN_DEBUG "mx1_touchscreen: mx1_pendata_irq interrupt recived from struct %p\n", mts);*/
439                 
440         if (mx1ts_reg_read(mts, ASP_ISTATR) & ASP_PUIS) {       /*pen up interupt pending*/
441                 mx1ts_reg_set_mask(mts, ASP_ISTATR, ASP_PUIS);  /*clearing pen up interupt*/
442
443                 mx1ts_disable_auto_sample(mts);                         
444                 mx1ts_disable_pen_up_interrupt(mts);
445                 mx1ts_enable_pen_touch_interrupt(mts);
446
447                 if(mts->is_open)                                        /*report last known touch*/
448                         mx1ts_evt_add_up(mts->ts_idev);
449                 printk(KERN_DEBUG "Pen up interrupt.\n");                       
450                 mx1ts_flush_fifo(mts);
451
452                 return IRQ_HANDLED;
453         }
454         
455         if (mts->auto_calibration) {
456 /*              unsigned int value;*/
457
458                 mts->cal_auto_zero = mx1ts_reg_read(mts, ASP_PADFIFO) & 0xFFFF;
459                 mts->cal_range_x = mx1ts_reg_read(mts, ASP_PADFIFO) & 0xFFFF;
460                 mts->cal_range_y = mx1ts_reg_read(mts, ASP_PADFIFO) & 0xFFFF;
461
462                 if ((mts->cal_auto_zero >= mts->cal_range_x) ||
463                     (mts->cal_auto_zero >= mts->cal_range_y)) {
464                         // Invalid data. 
465                         printk(KERN_INFO "Invalid calibration data. Recalibrating. \n");
466                         mx1ts_flush_fifo(mts);                  /*if there are some older data*/
467                         mx1ts_start_auto_calibration(mts);
468                         return IRQ_HANDLED; /*return IRQ_NONE;*/
469                 }
470
471                 printk(KERN_DEBUG "mx1 touchscreen: calibration cal_auto_zero %i.\n",mts->cal_auto_zero);
472                 printk(KERN_DEBUG "mx1 touchscreen: calibration cal_range_x %i.\n",mts->cal_range_x);
473                 printk(KERN_DEBUG "mx1 touchscreen: calibration cal_range_y %i.\n",mts->cal_range_y);
474                 
475                 mts->cal_range_x -= mts->cal_auto_zero;
476                 mts->cal_range_y -= mts->cal_auto_zero;
477                 
478                 
479                 /*
480                 value = mx1ts_reg_read(mts, ASP_ACNTLCR);  podle me duplicita
481                 value &= ~0x04000000; 
482                 mx1ts_reg_write(mts, ASP_ACNTLCR, value);
483                 */
484                 mts->auto_calibration = 0;
485
486                 mx1ts_enable_auto_sample(mts);
487         } else {
488                 // There could be more than one sample in the FIFO, but we're
489                 // only going to read one per call. The interrupt will be
490                 // generated as long as there is data in the FIFO. 
491
492                 if ((mx1ts_reg_read(mts, ASP_ISTATR) & ASP_PDR) != ASP_PDR) {
493                         return IRQ_NONE; 
494                 }
495
496                 auto_zero = mx1ts_reg_read(mts, ASP_PADFIFO);
497                 if (auto_zero > (mts->cal_auto_zero + 0x200)) {
498                         return IRQ_HANDLED; /* TODO asi se nic nedeje */
499                 }
500
501                 pen_x = mx1ts_reg_read(mts, ASP_PADFIFO);
502                 pen_y = mx1ts_reg_read(mts, ASP_PADFIFO);
503                 pen_u = mx1ts_reg_read(mts, ASP_PADFIFO);
504
505                 pen_x = (u32)(((pen_x - auto_zero) << 16) /
506                               mts->cal_range_x);
507                 pen_y = (u32)(((pen_y - auto_zero) << 16) /
508                               mts->cal_range_y);
509                 
510                 if(mts->is_open)
511                         mx1ts_evt_add_touch(mts->ts_idev, 200 , pen_x, pen_y);
512         }
513         return IRQ_HANDLED;
514 }
515
516 /*
517  * Handle the touch interrupt, generated when the pen is pressed/
518  * released.
519  */
520
521 static irqreturn_t mx1ts_touch_irq(int irq, void *dev_id)
522 {
523         struct mx1ts *mts = (struct mx1ts *) dev_id;
524         
525         printk(KERN_DEBUG "mx1 touchscreen: Touch down interrupt \n");  
526
527         /* Clear the interrupt. */
528         mx1ts_reg_set_mask(mts, ASP_ISTATR, ASP_PEN);
529
530         mx1ts_disable_pen_touch_interrupt(mts);
531         mx1ts_flush_fifo(mts);
532         mx1ts_start_auto_calibration(mts);
533         mx1ts_enable_pen_up_interrupt(mts);
534
535         return IRQ_HANDLED;
536 }
537
538 static inline int mx1ts_enable_irqs(struct mx1ts *mts)  //zaregistruje preruseni
539 {
540         int result;
541 //TODO  printk(KERN_ERR "enabling irq %d.\n",mts->ts_idev->dev.parent.resource[1]->start);
542         result = request_irq(ASP_PENDATA_IRQ,
543                              mx1ts_pendata_irq,
544                                  0,
545                              DEV_IRQ_ID,
546                              mts);
547         if (result) {
548                 printk(KERN_ERR "mx1 touchscreen: Couldn't request pen data IRQ.\n");
549                 return result;
550         }
551
552         result = request_irq(ASP_TOUCH_IRQ,
553                              mx1ts_touch_irq,
554                              /*IRQF_*/ 0,
555                              DEV_IRQ_ID,
556                              mts);
557         if (result) {
558                 printk(KERN_ERR "mx1 touchscreen: Couldn't request pen touch IRQ.\n");
559                 free_irq(ASP_PENDATA_IRQ, mts);
560                 return result;
561         }
562         return result;
563 }
564
565
566
567 static int mx1ts_on(struct mx1ts *mts)    /*TODO doplnit pri chybach*/
568 {
569         int ret = 0;
570         
571         if(!request_mem_region(ASP_BASE_ADDR, 0x38 , "mx1ts")) {
572                 printk(KERN_ERR "mx1 touchscreen: request_mem_region \tFAILED\n");
573                 return -1;      
574         }
575
576         printk(KERN_DEBUG "mx1 touchscreen: request_mem_region \tOK\n");        
577
578         mts->mx1ts_mem = ioremap ( ASP_BASE_ADDR, 0x38);
579         
580         if(!mts->mx1ts_mem) {
581                 printk(KERN_ERR "mx1 touchscreen: ioremap  \tFAILED\n");
582                 return -1;      
583         }
584
585         printk(KERN_DEBUG "mx1 touchscreen: memory remaped on %p \n", mts->mx1ts_mem);
586         
587
588
589         /*printk(KERN_DEBUG "mx1 touchscreen: enabling irqs\n");*/
590         if ((ret = mx1ts_enable_irqs(mts)))
591                 return ret;
592         printk(KERN_DEBUG "mx1 touchscreen: irqs enabled \tOK\n");      
593
594         
595         mx1ts_reset_asp(mts);
596         printk(KERN_DEBUG "mx1 touchscreen: reset\tOK\n");
597         
598         return 0;
599 }
600
601 static void mx1ts_close(struct input_dev *idev)
602 {
603         struct mx1ts *mts = dev_get_drvdata(idev->dev.parent);
604         mts->is_open = 0;
605         mx1ts_flush_fifo(mts);
606         mx1ts_reset_asp(mts);
607         printk(KERN_DEBUG "mx1 touchscreen: reset\tOK\n");
608         mx1ts_disable_pen_touch_interrupt(mts);
609         mx1ts_disable_pen_up_interrupt(mts);
610
611 }
612
613 static int mx1ts_open(struct input_dev *idev)
614 {
615         struct mx1ts *mts = dev_get_drvdata(idev->dev.parent);
616         mts->is_open = 1;
617         mx1ts_flush_fifo(mts);                  /*if there are some older data*/
618         mx1ts_enable_pen_touch_interrupt(mts);
619         printk(KERN_DEBUG "mx1 touchscreen: touch_down interupt enabled\n");    
620         return 0;
621 }
622
623 static int mx1ts_probe(struct platform_device *dev)
624 {
625         struct mx1ts *mts;
626         struct input_dev *idev;
627         int error, x_res, y_res;
628
629         /* TODO jak poznat ze zarizeni je pritomne ? */
630
631         mts = kzalloc(sizeof(struct mx1ts), GFP_KERNEL);        /* alokuje pamet */
632         idev = input_allocate_device();
633         if (!mts || !idev) {
634                 error = -ENOMEM;
635                 printk(KERN_ERR "mx1 touchscreen: failed allocate memory for struct mx1ts or idev\n");  
636                 goto err_free_devs;
637                 return error;   
638         }
639         
640         mx1ts_on(mts);                  /* remaping registers, reseting device */
641
642         mts->ts_idev = idev;
643         init_waitqueue_head(&mts->ts_wait);
644
645         //input_set_drvdata(idev, mts);         /*moznost ulozit ukazatel na trukturu do input_driver*/
646         platform_set_drvdata(dev, mts);
647
648         idev->dev.parent        = &dev->dev;
649         idev->name              = "MX1 touchscreen interface";
650         idev->phys              = "mx1ts/input0";       //dodano
651         idev->id.vendor         = (unsigned int) 345;   /*mx1ts_reg_read(mx1_ts, AC97_VENDOR_ID1);*/
652         idev->id.product        = (unsigned int) 354;   /*id;*/
653         idev->id.version        = 0x0100;               //dodano
654         idev->id.bustype        = BUS_HOST;
655         idev->open              = mx1ts_open;
656         idev->close             = mx1ts_close;
657         idev->evbit[0]          = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
658         idev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
659
660         printk(KERN_DEBUG "mx1ts: setting idev struct \tOK\n");
661         
662         x_res = 60000;          /*TODO neni mozne zmerit ? */
663         y_res = 60000;
664         printk(KERN_DEBUG "mx1ts: x/y = %d/%d\n", x_res, y_res);
665
666         input_set_abs_params(idev, ABS_X, 0, x_res, 0, 0);
667         input_set_abs_params(idev, ABS_Y, 0, y_res, 0, 0);
668         input_set_abs_params(idev, ABS_PRESSURE, 0, 1, 0, 0);
669
670         error = input_register_device(idev);
671         if (error) {
672                 printk(KERN_ERR "mx1 touchscreen: error while register input device\n");
673                 goto err_free_devs;
674                 }
675
676         printk(KERN_DEBUG "mx1ts: input device registered \tOK\n");
677
678         return 0;
679
680   err_free_devs:
681         printk(KERN_ERR "mx1 touchscreen: error in device probe  \n");
682         /*input_free_device(idev);*/
683         kfree(mts);
684         return error;
685
686
687
688
689
690 static int mx1ts_remove(struct platform_device *dev)
691 {
692         struct mx1ts *mts = platform_get_drvdata(dev);
693
694         //BUG_ON(mts == NULL);
695         
696         free_irq(ASP_PENDATA_IRQ, mts);
697         free_irq(ASP_TOUCH_IRQ, mts);
698
699         /*input_free_device(mts->ts_idev);
700         printk(KERN_DEBUG "Free device \tOK\n");*/
701         
702         input_unregister_device(mts->ts_idev);
703         printk(KERN_INFO "mx1 touchscreen: Unregister device \tOK\n");
704         iounmap(mts->mx1ts_mem);
705         release_mem_region(ASP_BASE_ADDR, 0x38);
706                 
707         kfree(mts);
708
709         printk(KERN_INFO "mx1 touchscreen: Removing driver \tOK\n");
710         return 0;
711 }
712
713
714
715 static int mx1ts_resume(struct platform_device *dev)
716 {
717         return 0;
718 }
719
720 /* inicializace ovladace a driveru (insmod, rmmmod ) */
721
722 static struct platform_driver mx1ts_driver = {
723         .probe = mx1ts_probe,
724         .remove = mx1ts_remove,
725         .resume = mx1ts_resume,
726         .driver = {
727                 .name           = "mx1ts",
728                 .owner          = THIS_MODULE,
729                 },
730 };
731
732 static struct resource mx1ts_resources[] = {
733         [0] = {
734                 .start  = ASP_BASE_ADDR + 0,
735                 .end    = ASP_BASE_ADDR + 0x37,
736                 .flags  = IORESOURCE_MEM,
737         },
738         [1] = {
739                 .start  = ASP_PENDATA_IRQ,
740                 .end    = ASP_PENDATA_IRQ,
741                 .flags  = IORESOURCE_IRQ,
742         },
743         [2] = {
744                 .start  = ASP_TOUCH_IRQ,
745                 .end    = ASP_TOUCH_IRQ,
746                 .flags  = IORESOURCE_IRQ,
747         },
748 };
749
750 void mx1ts_device_release(struct device *dev) {
751         /*struct platform_device *pdev = to_platform_device(dev);
752         release_resource(&dev->res);
753         kfree(pdev);
754         }*/
755 }
756
757 static struct platform_device mx1ts_device = {
758         .name           = "mx1ts",
759         .id             = 0,
760         .num_resources  = ARRAY_SIZE(mx1ts_resources),
761         .resource       = mx1ts_resources,
762         .dev = {
763         .release = mx1ts_device_release,
764         },
765 };
766
767
768
769
770 static int __init mx1ts_init(void)
771 {
772
773         int error;
774         error = platform_device_register(&mx1ts_device);
775         if(error) {
776                 printk(KERN_ERR "mx1 touchscreen: device registration failed\n");
777                 return error;
778         }
779
780
781         error = platform_driver_register(&mx1ts_driver);
782         if (error) {
783                 printk(KERN_ERR "mx1_touchscreen: failed to register touchscreen driver, error: %d\n", error);
784                 platform_device_unregister(&mx1ts_device);
785                 return error;
786         }
787         
788                 
789         return 0;
790         
791 }
792
793 static void __exit mx1ts_exit(void)
794 {
795         platform_driver_unregister(&mx1ts_driver);              
796         platform_device_unregister(&mx1ts_device);
797         
798         return;
799 }                            
800
801 //module_param(adcsync, bool, 0444);
802 //MODULE_PARM_DESC(adcsync, "Synchronize touch readings with ADCSYNC pin.");
803
804 //module_param(ts_delay, int, 0444);
805 //MODULE_PARM_DESC(ts_delay, "Delay between panel setup and position read. Default = 55us.");
806
807 //module_param(ts_delay_pressure, int, 0444);
808 //MODULE_PARM_DESC(ts_delay_pressure,
809 //                "delay between panel setup and pressure read.  Default = 0us.");
810
811 module_init(mx1ts_init);
812 module_exit(mx1ts_exit);
813
814
815 MODULE_DESCRIPTION("MX1 touchscreen driver");
816 MODULE_AUTHOR("Radek Pupák (pupakr1@fel.cvut.cz)");
817 MODULE_LICENSE("GPL");
818