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