]> rtime.felk.cvut.cz Git - mx1ts.git/blob - mx1_ts-driver.c
po oprave odporu mezi PX1 a napajenim, funguji preruseni, netreba ignorovat urcite...
[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 static int MX1TS_lastx = 0;
187 static int MX1TS_lasty = 0;
188
189 static inline void mx1ts_reg_set_mask(struct mx1ts *mts , unsigned int reg, u32 mask)
190 {       
191         u32 val;
192         val = __raw_readl(mts->mx1ts_mem+reg);
193         val |= mask;
194         __raw_writel(val, mts->mx1ts_mem+reg );
195 }
196
197 static inline void mx1ts_reg_clear_mask(struct mx1ts *mts , unsigned int reg, u32 mask)
198 {       
199         u32 val;
200         val = __raw_readl(mts->mx1ts_mem+reg);
201         val &= mask;
202         __raw_writel(val, mts->mx1ts_mem+reg );
203 }
204
205 static inline void mx1ts_reg_write(struct mx1ts *mts, unsigned int reg, unsigned int val)
206 {       
207         __raw_writel(val, mts->mx1ts_mem+reg);
208         printk(KERN_DEBUG "mx1_touchscreen: writing into : %p value %x\n",mts->mx1ts_mem+reg, val);
209         
210 }
211
212 static inline unsigned int mx1ts_reg_read(struct mx1ts *mts, unsigned int reg)
213 {
214         unsigned int out;
215
216         out =  __raw_readl( mts->mx1ts_mem + reg );     
217         /*printk(KERN_DEBUG "mx1_touchscreen: reading from %p : %d \n",mts->mx1ts_mem + reg, out);*/
218                 
219         return out;
220 }
221
222 static inline void mx1ts_flush_fifo(struct mx1ts *mts)
223 {
224         int i;
225         for (i = 0; i < 12; i++)
226                 if (mx1ts_reg_read(mts, ASP_ISTATR) & (ASP_PFF | ASP_PDR))
227                         mx1ts_reg_read(mts, ASP_PADFIFO);
228 }
229
230 static void mx1ts_enable_auto_sample(struct mx1ts *mts)
231 {
232         unsigned int value;
233
234         mx1ts_flush_fifo(mts);
235
236         value = mx1ts_reg_read(mts, ASP_ACNTLCR);
237
238         /* Set the mode to X then Y */
239         value &= ~ASP_MODE_MASK;
240         value |= ASP_MODE_ONLY_Y;
241
242         /* Enable auto zero. */
243         value |= ASP_AZE;
244
245         /* Enable auto sample. */
246         value |= ASP_AUTO;
247
248         /* Enable pen A/D. */
249         value |= ASP_PADE;
250         mx1ts_reg_write(mts, ASP_ACNTLCR, value);
251
252         /* Enable pen data ready and full interrupt. */
253         value = mx1ts_reg_read(mts, ASP_ICNTLR);
254         value |= ASP_PFFE | ASP_PDRE;
255         mx1ts_reg_write(mts, ASP_ICNTLR, value);
256 }
257
258
259 static void mx1ts_disable_auto_sample(struct mx1ts *mts)
260 {
261         unsigned int value;
262
263         value = mx1ts_reg_read(mts, ASP_ACNTLCR);
264
265         /* Set the mode to none */
266         value &= ~ASP_MODE_MASK;
267
268         /* Disable auto zero. */
269         value &= ~ASP_AZE;
270
271         /* Disable auto sample. */
272         value &= ~ASP_AUTO;
273
274         /* Disable pen A/D. */
275         value &= ~ASP_PADE;
276         mx1ts_reg_write(mts, ASP_ACNTLCR, value);
277
278         /* Disable pen data ready and full interrupt. */
279         value = mx1ts_reg_read(mts, ASP_ICNTLR);
280         value &= ~(ASP_PFFE | ASP_PDRE);
281         mx1ts_reg_write(mts, ASP_ICNTLR, value);
282 }
283
284 static void mx1ts_enable_pen_touch_interrupt(struct mx1ts *mts)
285 {
286         unsigned int value;
287
288         /* Enable pen touch interrupt. */
289         value = mx1ts_reg_read(mts, ASP_ICNTLR);
290         value |= ASP_EDGE | /*ASP_POL |*/ ASP_PIRQE;
291         mx1ts_reg_write(mts, ASP_ICNTLR, value);
292         
293         printk(KERN_DEBUG "mx1_touchscreen: pen_touch: activating pen_down interrupt \n");
294 }
295
296 static void mx1ts_disable_pen_touch_interrupt(struct mx1ts *mts)
297 {
298         unsigned int value;
299
300         /* Enable pen touch interrupt. */
301         value = mx1ts_reg_read(mts, ASP_ICNTLR);
302         value &= ~ASP_PIRQE;
303         mx1ts_reg_write(mts, ASP_ICNTLR, value);
304         printk(KERN_DEBUG "mx1_touchscreen: pen_touch: deaktivating pen_down interrupt \n");
305 }
306
307 static void mx1ts_enable_pen_up_interrupt(struct mx1ts *mts)
308 {
309         unsigned int value;
310
311         value = mx1ts_reg_read(mts, ASP_ICNTLR);
312         value |= ASP_PUIE; 
313         mx1ts_reg_write(mts, ASP_ICNTLR, value);
314         printk(KERN_DEBUG "mx1_touchscreen: pen_up: activating pen_up interrupt \n");
315 }
316
317 static void mx1ts_disable_pen_up_interrupt(struct mx1ts *mts)
318 {
319         unsigned int value;
320
321         /* Enable pen up interrupt.  */
322         value = mx1ts_reg_read(mts, ASP_ICNTLR);
323         value &= ~ASP_PUIE;
324         mx1ts_reg_write(mts, ASP_ICNTLR, value);
325         printk(KERN_DEBUG "mx1_touchscreen: pen_up: deaktivating pen_up interrupt \n");
326 }
327
328
329
330 static void mx1ts_start_auto_calibration(struct mx1ts *mts)
331 {
332         unsigned int value;
333         printk(KERN_DEBUG "mx1_touchscreen: start_auto_calibration \n");
334
335
336         mts->auto_calibration = 1;
337
338         value = mx1ts_reg_read(mts, ASP_ACNTLCR);
339
340         /* Set the mode to X then Y */
341         value &= ~ASP_MODE_MASK;
342         value |= ASP_MODE_ONLY_X;
343
344         /* Enable auto zero. */
345         value |= ASP_AZE;
346
347         /* Enable auto calibrate. XXX: Undocumented bitfield. */
348         value |= 0x04000000;
349
350         /* Enable auto sample. */
351         value |= ASP_AUTO;
352
353         /* Enable pen A/D. */
354         value |= ASP_PADE;
355         mx1ts_reg_write(mts, ASP_ACNTLCR, value);
356
357         /* Enable pen data ready and full interrupt. */
358         value = mx1ts_reg_read(mts, ASP_ICNTLR);
359         value |= ASP_PFFE | ASP_PDRE | ASP_PUIE;
360         mx1ts_reg_write(mts, ASP_ICNTLR, value);
361 }
362
363 static void mx1ts_reset_asp(struct mx1ts *mts)
364 {
365         unsigned int value;
366
367         mx1ts_flush_fifo(mts);
368
369         /* Soft reset the ASP module */
370         mx1ts_reg_write(mts, ASP_ACNTLCR, ASP_SWRST);
371         /* Read back the reset value of the control register */
372         value = mx1ts_reg_read(mts, ASP_ACNTLCR);
373
374         /* Enable the clock and wait for a short while */
375         value |= ASP_CLKEN;
376         mx1ts_reg_write(mts, ASP_ACNTLCR, value);
377         udelay(100);
378
379         /* Set the value of the conrtol register. */
380         value = ASP_CLKEN | ASP_NM | ASP_SW6 | ASP_BGE;
381         mx1ts_reg_write(mts, ASP_ACNTLCR, value);
382
383         /* 0x01 Set the clock divide ratio to 2. */
384         mx1ts_reg_write(mts, ASP_CLKDIV, 0x1f);
385
386         /* Set the sample rate control register. These values should yield
387          * about 150 samples per second, which seems to give good smooth
388          * lines. */
389         value = (0x7 << ASP_DMCNT_SCALE) |      /* 0x2 - Decimation ratio is 3 */
390                 (0x3F << ASP_IDLECNT_SCALE) |   /* 0x1 - Idle count is 1 clock */
391                 (0xF << ASP_DSCNT_SCALE);       /* 0x2 - Data setup is 2 clocks */
392         mx1ts_reg_write(mts, ASP_PSMPLRG, value);
393
394         /* Disable the compare function. */
395         mx1ts_reg_write(mts, ASP_CMPCNTL, 0);
396 }
397
398 static void mx1ts_evt_add_touch(struct input_dev *idev, u8 p , u16 x, u16 y)
399 {
400         input_report_key(idev, BTN_TOUCH, 1);
401         input_report_abs(idev, ABS_X, x);
402         input_report_abs(idev, ABS_Y, y);
403         /*input_report_abs(idev, ABS_PRESSURE, p);*/
404         input_report_abs(idev, ABS_PRESSURE, 1);
405         MX1TS_lastx = x;
406         MX1TS_lasty = y;
407         input_sync(idev);
408 }
409
410 static void mx1ts_evt_add_up(struct input_dev *idev)
411 {
412         input_report_abs(idev, ABS_X, MX1TS_lastx);
413         input_report_abs(idev, ABS_Y, MX1TS_lasty);
414         input_report_abs(idev, ABS_PRESSURE, 0);
415         /*input_report_key(idev, BTN_TOUCH, 0);*/
416         input_sync(idev);
417 }
418
419 /*
420  * Handle the pen data ready interrupt, generated when pen data is
421  * in the FIFO.
422  */
423
424 static irqreturn_t mx1ts_pendata_irq(int irq, void *dev_id)
425 {       
426         
427         struct mx1ts *mts = (struct mx1ts *)dev_id;
428         u16 mx1_cal_range_x;
429         u16 mx1_cal_range_y;
430         static unsigned int auto_zero, pen_x, pen_y, pen_u;
431
432         mx1_cal_range_x = 1;
433         mx1_cal_range_y = 1;
434
435         /*printk(KERN_DEBUG "mx1_touchscreen mx1ts_pendata_irq \n");*/
436 /*      printk(KERN_DEBUG "mx1_touchscreen: mx1_pendata_irq interrupt recived from struct %p\n", mts);*/
437                 
438         if (mx1ts_reg_read(mts, ASP_ISTATR) & ASP_PUIS) {       /*pen up interupt pending*/
439                 mx1ts_reg_set_mask(mts, ASP_ISTATR, ASP_PUIS);  /*clearing pen up interupt*/
440
441                 mx1ts_disable_auto_sample(mts);                         
442                 mx1ts_disable_pen_up_interrupt(mts);
443                 mx1ts_enable_pen_touch_interrupt(mts);
444
445                 if(mts->is_open)                                        /*report last known touch*/
446                         mx1ts_evt_add_up(mts->ts_idev);
447                 printk(KERN_DEBUG "Pen up interrupt.\n");                       
448                 mx1ts_flush_fifo(mts);
449
450                 return IRQ_HANDLED;
451         }
452         
453         if (mts->auto_calibration) {
454 /*              unsigned int value;*/
455
456                 mts->cal_auto_zero = mx1ts_reg_read(mts, ASP_PADFIFO) & 0xFFFF;
457                 mts->cal_range_x = mx1ts_reg_read(mts, ASP_PADFIFO) & 0xFFFF;
458                 mts->cal_range_y = mx1ts_reg_read(mts, ASP_PADFIFO) & 0xFFFF;
459
460                 if ((mts->cal_auto_zero >= mts->cal_range_x) ||
461                     (mts->cal_auto_zero >= mts->cal_range_y)) {
462                         // Invalid data. 
463                         printk(KERN_INFO "Invalid calibration data. Recalibrating. \n");
464                         mx1ts_flush_fifo(mts);                  /*if there are some older data*/
465                         mx1ts_start_auto_calibration(mts);
466                         return IRQ_HANDLED; /*return IRQ_NONE;*/
467                 }
468
469                 printk(KERN_DEBUG "mx1 touchscreen: calibration cal_auto_zero %i.\n",mts->cal_auto_zero);
470                 printk(KERN_DEBUG "mx1 touchscreen: calibration cal_range_x %i.\n",mts->cal_range_x);
471                 printk(KERN_DEBUG "mx1 touchscreen: calibration cal_range_y %i.\n",mts->cal_range_y);
472                 
473                 mts->cal_range_x -= mts->cal_auto_zero;
474                 mts->cal_range_y -= mts->cal_auto_zero;
475                 
476                 
477                 /*
478                 value = mx1ts_reg_read(mts, ASP_ACNTLCR);  podle me duplicita
479                 value &= ~0x04000000; 
480                 mx1ts_reg_write(mts, ASP_ACNTLCR, value);
481                 */
482                 mts->auto_calibration = 0;
483
484                 mx1ts_enable_auto_sample(mts);
485         } else {
486                 // There could be more than one sample in the FIFO, but we're
487                 // only going to read one per call. The interrupt will be
488                 // generated as long as there is data in the FIFO. 
489
490                 if ((mx1ts_reg_read(mts, ASP_ISTATR) & ASP_PDR) != ASP_PDR) {
491                         return IRQ_NONE; 
492                 }
493
494                 auto_zero = mx1ts_reg_read(mts, ASP_PADFIFO);
495                 if (auto_zero > (mts->cal_auto_zero + 0x200)) {
496                         return IRQ_HANDLED; /* TODO asi se nic nedeje */
497                 }
498
499                 pen_x = mx1ts_reg_read(mts, ASP_PADFIFO);
500                 pen_y = mx1ts_reg_read(mts, ASP_PADFIFO);
501                 pen_u = mx1ts_reg_read(mts, ASP_PADFIFO);
502
503                 pen_x = (u32)(((pen_x - auto_zero) << 16) /
504                               mts->cal_range_x);
505                 pen_y = (u32)(((pen_y - auto_zero) << 16) /
506                               mts->cal_range_y);
507                 
508                 if(mts->is_open)
509                         mx1ts_evt_add_touch(mts->ts_idev, 200 , pen_x, pen_y);
510         }
511         return IRQ_HANDLED;
512 }
513
514 /*
515  * Handle the touch interrupt, generated when the pen is pressed/
516  * released.
517  */
518
519 static irqreturn_t mx1ts_touch_irq(int irq, void *dev_id)
520 {
521         struct mx1ts *mts = (struct mx1ts *) dev_id;
522         
523         printk(KERN_ERR "mx1 touchscreen: Touch down interrupt \n");    
524
525         /* Clear the interrupt. */
526         mx1ts_reg_set_mask(mts, ASP_ISTATR, ASP_PEN);
527
528         mx1ts_disable_pen_touch_interrupt(mts);
529         mx1ts_flush_fifo(mts);
530         mx1ts_start_auto_calibration(mts);
531         mx1ts_enable_pen_up_interrupt(mts);
532
533         return IRQ_HANDLED;
534 }
535
536 static inline int mx1ts_enable_irqs(struct mx1ts *mts)  //zaregistruje preruseni
537 {
538         int result;
539 //TODO  printk(KERN_ERR "enabling irq %d.\n",mts->ts_idev->dev.parent.resource[1]->start);
540         result = request_irq(ASP_PENDATA_IRQ,
541                              mx1ts_pendata_irq,
542                                  0,
543                              DEV_IRQ_ID,
544                              mts);
545         if (result) {
546                 printk(KERN_ERR "mx1 touchscreen: Couldn't request pen data IRQ.\n");
547                 return result;
548         }
549
550         result = request_irq(ASP_TOUCH_IRQ,
551                              mx1ts_touch_irq,
552                              /*IRQF_*/ 0,
553                              DEV_IRQ_ID,
554                              mts);
555         if (result) {
556                 printk(KERN_ERR "mx1 touchscreen: Couldn't request pen touch IRQ.\n");
557                 free_irq(ASP_PENDATA_IRQ, mts);
558                 return result;
559         }
560         return result;
561 }
562
563
564
565 static int mx1ts_on(struct mx1ts *mts)    /*TODO doplnit pri chybach*/
566 {
567         int ret = 0;
568         
569         if(!request_mem_region(ASP_BASE_ADDR, 0x38 , "mx1ts")) {
570                 printk(KERN_ERR "mx1 touchscreen: request_mem_region \tFAILED\n");
571                 return -1;      
572         }
573
574         printk(KERN_DEBUG "mx1 touchscreen: request_mem_region \tOK\n");        
575
576         mts->mx1ts_mem = ioremap ( ASP_BASE_ADDR, 0x38);
577         
578         if(!mts->mx1ts_mem) {
579                 printk(KERN_ERR "mx1 touchscreen: ioremap  \tFAILED\n");
580                 return -1;      
581         }
582
583         printk(KERN_DEBUG "mx1 touchscreen: memory remaped on %p \n", mts->mx1ts_mem);
584         
585
586
587         /*printk(KERN_DEBUG "mx1 touchscreen: enabling irqs\n");*/
588         if ((ret = mx1ts_enable_irqs(mts)))
589                 return ret;
590         printk(KERN_DEBUG "mx1 touchscreen: irqs enabled \tOK\n");      
591
592         
593         mx1ts_reset_asp(mts);
594         printk(KERN_DEBUG "mx1 touchscreen: reset\tOK\n");
595         
596         return 0;
597 }
598
599 static void mx1ts_close(struct input_dev *idev)
600 {
601         struct mx1ts *mts = dev_get_drvdata(idev->dev.parent);
602         mts->is_open = 0;
603         mx1ts_flush_fifo(mts);
604         mx1ts_reset_asp(mts);
605         printk(KERN_DEBUG "mx1 touchscreen: reset\tOK\n");
606         mx1ts_disable_pen_touch_interrupt(mts);
607         mx1ts_disable_pen_up_interrupt(mts);
608
609 }
610
611 static int mx1ts_open(struct input_dev *idev)
612 {
613         struct mx1ts *mts = dev_get_drvdata(idev->dev.parent);
614         mts->is_open = 1;
615         mx1ts_flush_fifo(mts);                  /*if there are some older data*/
616         mx1ts_enable_pen_touch_interrupt(mts);
617         printk(KERN_DEBUG "mx1 touchscreen: touch_down interupt enabled\n");    
618         return 0;
619 }
620
621 static int mx1ts_probe(struct platform_device *dev)
622 {
623         struct mx1ts *mts;
624         struct input_dev *idev;
625         int error, x_res, y_res;
626
627         /* TODO jak poznat ze zarizeni je pritomne ? */
628
629         mts = kzalloc(sizeof(struct mx1ts), GFP_KERNEL);        /* alokuje pamet */
630         idev = input_allocate_device();
631         if (!mts || !idev) {
632                 error = -ENOMEM;
633                 printk(KERN_ERR "mx1 touchscreen: failed allocate memory for struct mx1ts or idev\n");  
634                 goto err_free_devs;
635                 return error;   
636         }
637         
638         mx1ts_on(mts);                  /* remaping registers, reseting device */
639
640         mts->ts_idev = idev;
641         init_waitqueue_head(&mts->ts_wait);
642
643         //input_set_drvdata(idev, mts);         /*moznost ulozit ukazatel na trukturu do input_driver*/
644         platform_set_drvdata(dev, mts);
645
646         idev->dev.parent        = &dev->dev;
647         idev->name              = "MX1 touchscreen interface";
648         idev->phys              = "mx1ts/input0";       //dodano
649         idev->id.vendor         = (unsigned int) 345;   /*mx1ts_reg_read(mx1_ts, AC97_VENDOR_ID1);*/
650         idev->id.product        = (unsigned int) 354;   /*id;*/
651         idev->id.version        = 0x0100;               //dodano
652         idev->id.bustype        = BUS_HOST;
653         idev->open              = mx1ts_open;
654         idev->close             = mx1ts_close;
655         idev->evbit[0]          = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
656         idev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
657
658         printk(KERN_DEBUG "mx1ts: setting idev struct \tOK\n");
659         
660         x_res = 60000;          /*TODO neni mozne zmerit ? */
661         y_res = 60000;
662         printk(KERN_DEBUG "mx1ts: x/y = %d/%d\n", x_res, y_res);
663
664         input_set_abs_params(idev, ABS_X, 0, x_res, 0, 0);
665         input_set_abs_params(idev, ABS_Y, 0, y_res, 0, 0);
666         input_set_abs_params(idev, ABS_PRESSURE, 0, 1, 0, 0);
667
668         error = input_register_device(idev);
669         if (error) {
670                 printk(KERN_ERR "mx1 touchscreen: error while register input device\n");
671                 goto err_free_devs;
672                 }
673
674         printk(KERN_DEBUG "mx1ts: input device registered \tOK\n");
675
676         return 0;
677
678   err_free_devs:
679         printk(KERN_ERR "mx1 touchscreen: error in device probe  \n");
680         /*input_free_device(idev);*/
681         kfree(mts);
682         return error;
683
684
685
686
687
688 static int mx1ts_remove(struct platform_device *dev)
689 {
690         struct mx1ts *mts = platform_get_drvdata(dev);
691
692         //BUG_ON(mts == NULL);
693         
694         free_irq(ASP_PENDATA_IRQ, mts);
695         free_irq(ASP_TOUCH_IRQ, mts);
696
697         /*input_free_device(mts->ts_idev);
698         printk(KERN_DEBUG "Free device \tOK\n");*/
699         
700         input_unregister_device(mts->ts_idev);
701         printk(KERN_INFO "mx1 touchscreen: Unregister device \tOK\n");
702         iounmap(mts->mx1ts_mem);
703         release_mem_region(ASP_BASE_ADDR, 0x38);
704                 
705         kfree(mts);
706
707         printk(KERN_INFO "mx1 touchscreen: Removing driver \tOK\n");
708         return 0;
709 }
710
711
712
713 static int mx1ts_resume(struct platform_device *dev)
714 {
715         return 0;
716 }
717
718 /* inicializace ovladace a driveru (insmod, rmmmod ) */
719
720 static struct platform_driver mx1ts_driver = {
721         .probe = mx1ts_probe,
722         .remove = mx1ts_remove,
723         .resume = mx1ts_resume,
724         .driver = {
725                 .name           = "mx1ts",
726                 .owner          = THIS_MODULE,
727                 },
728 };
729
730 static struct resource mx1ts_resources[] = {
731         [0] = {
732                 .start  = ASP_BASE_ADDR + 0,
733                 .end    = ASP_BASE_ADDR + 0x37,
734                 .flags  = IORESOURCE_MEM,
735         },
736         [1] = {
737                 .start  = ASP_PENDATA_IRQ,
738                 .end    = ASP_PENDATA_IRQ,
739                 .flags  = IORESOURCE_IRQ,
740         },
741         [2] = {
742                 .start  = ASP_TOUCH_IRQ,
743                 .end    = ASP_TOUCH_IRQ,
744                 .flags  = IORESOURCE_IRQ,
745         },
746 };
747
748 void mx1ts_device_release(struct device *dev) {
749         /*struct platform_device *pdev = to_platform_device(dev);
750         release_resource(&dev->res);
751         kfree(pdev);
752         }*/
753 }
754
755 static struct platform_device mx1ts_device = {
756         .name           = "mx1ts",
757         .id             = 0,
758         .num_resources  = ARRAY_SIZE(mx1ts_resources),
759         .resource       = mx1ts_resources,
760         .dev = {
761         .release = mx1ts_device_release,
762         },
763 };
764
765
766
767
768 static int __init mx1ts_init(void)
769 {
770
771         int error;
772         error = platform_device_register(&mx1ts_device);
773         if(error) {
774                 printk(KERN_ERR "mx1 touchscreen: device registration failed\n");
775                 return error;
776         }
777
778
779         error = platform_driver_register(&mx1ts_driver);
780         if (error) {
781                 printk(KERN_ERR "mx1_touchscreen: failed to register touchscreen driver, error: %d\n", error);
782                 platform_device_unregister(&mx1ts_device);
783                 return error;
784         }
785         
786                 
787         return 0;
788         
789 }
790
791 static void __exit mx1ts_exit(void)
792 {
793         platform_driver_unregister(&mx1ts_driver);              
794         platform_device_unregister(&mx1ts_device);
795         
796         return;
797 }                            
798
799 //module_param(adcsync, bool, 0444);
800 //MODULE_PARM_DESC(adcsync, "Synchronize touch readings with ADCSYNC pin.");
801
802 //module_param(ts_delay, int, 0444);
803 //MODULE_PARM_DESC(ts_delay, "Delay between panel setup and position read. Default = 55us.");
804
805 //module_param(ts_delay_pressure, int, 0444);
806 //MODULE_PARM_DESC(ts_delay_pressure,
807 //                "delay between panel setup and pressure read.  Default = 0us.");
808
809 module_init(mx1ts_init);
810 module_exit(mx1ts_exit);
811
812
813 MODULE_DESCRIPTION("MX1 touchscreen driver");
814 MODULE_AUTHOR("Radek Pupák (pupakr1@fel.cvut.cz)");
815 MODULE_LICENSE("GPL");
816