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