pandora: update defconfig
[pandora-kernel.git] / drivers / pcmcia / m32r_pcc.c
1 /*
2  *  drivers/pcmcia/m32r_pcc.c
3  *
4  *  Device driver for the PCMCIA functionality of M32R.
5  *
6  *  Copyright (c) 2001, 2002, 2003, 2004
7  *    Hiroyuki Kondo, Naoto Sugai, Hayato Fujiwara
8  */
9
10 #include <linux/module.h>
11 #include <linux/moduleparam.h>
12 #include <linux/init.h>
13 #include <linux/types.h>
14 #include <linux/fcntl.h>
15 #include <linux/string.h>
16 #include <linux/kernel.h>
17 #include <linux/errno.h>
18 #include <linux/timer.h>
19 #include <linux/ioport.h>
20 #include <linux/delay.h>
21 #include <linux/workqueue.h>
22 #include <linux/interrupt.h>
23 #include <linux/platform_device.h>
24 #include <linux/bitops.h>
25 #include <asm/irq.h>
26 #include <asm/io.h>
27 #include <asm/system.h>
28 #include <asm/addrspace.h>
29
30 #include <pcmcia/cs_types.h>
31 #include <pcmcia/ss.h>
32 #include <pcmcia/cs.h>
33
34 /* XXX: should be moved into asm/irq.h */
35 #define PCC0_IRQ 24
36 #define PCC1_IRQ 25
37
38 #include "m32r_pcc.h"
39
40 #define CHAOS_PCC_DEBUG
41 #ifdef CHAOS_PCC_DEBUG
42         static volatile u_short dummy_readbuf;
43 #endif
44
45 #define PCC_DEBUG_DBEX
46
47
48 /* Poll status interval -- 0 means default to interrupt */
49 static int poll_interval = 0;
50
51 typedef enum pcc_space { as_none = 0, as_comm, as_attr, as_io } pcc_as_t;
52
53 typedef struct pcc_socket {
54         u_short                 type, flags;
55         struct pcmcia_socket    socket;
56         unsigned int            number;
57         unsigned int            ioaddr;
58         u_long                  mapaddr;
59         u_long                  base;   /* PCC register base */
60         u_char                  cs_irq, intr;
61         pccard_io_map           io_map[MAX_IO_WIN];
62         pccard_mem_map          mem_map[MAX_WIN];
63         u_char                  io_win;
64         u_char                  mem_win;
65         pcc_as_t                current_space;
66         u_char                  last_iodbex;
67 #ifdef CHAOS_PCC_DEBUG
68         u_char                  last_iosize;
69 #endif
70 #ifdef CONFIG_PROC_FS
71         struct proc_dir_entry *proc;
72 #endif
73 } pcc_socket_t;
74
75 static int pcc_sockets = 0;
76 static pcc_socket_t socket[M32R_MAX_PCC] = {
77         { 0, }, /* ... */
78 };
79
80 /*====================================================================*/
81
82 static unsigned int pcc_get(u_short, unsigned int);
83 static void pcc_set(u_short, unsigned int , unsigned int );
84
85 static DEFINE_SPINLOCK(pcc_lock);
86
87 void pcc_iorw(int sock, unsigned long port, void *buf, size_t size, size_t nmemb, int wr, int flag)
88 {
89         u_long addr;
90         u_long flags;
91         int need_ex;
92 #ifdef PCC_DEBUG_DBEX
93         int _dbex;
94 #endif
95         pcc_socket_t *t = &socket[sock];
96 #ifdef CHAOS_PCC_DEBUG
97         int map_changed = 0;
98 #endif
99
100         /* Need lock ? */
101         spin_lock_irqsave(&pcc_lock, flags);
102
103         /*
104          * Check if need dbex
105          */
106         need_ex = (size > 1 && flag == 0) ? PCMOD_DBEX : 0;
107 #ifdef PCC_DEBUG_DBEX
108         _dbex = need_ex;
109         need_ex = 0;
110 #endif
111
112         /*
113          * calculate access address
114          */
115         addr = t->mapaddr + port - t->ioaddr + KSEG1; /* XXX */
116
117         /*
118          * Check current mapping
119          */
120         if (t->current_space != as_io || t->last_iodbex != need_ex) {
121
122                 u_long cbsz;
123
124                 /*
125                  * Disable first
126                  */
127                 pcc_set(sock, PCCR, 0);
128
129                 /*
130                  * Set mode and io address
131                  */
132                 cbsz = (t->flags & MAP_16BIT) ? 0 : PCMOD_CBSZ;
133                 pcc_set(sock, PCMOD, PCMOD_AS_IO | cbsz | need_ex);
134                 pcc_set(sock, PCADR, addr & 0x1ff00000);
135
136                 /*
137                  * Enable and read it
138                  */
139                 pcc_set(sock, PCCR, 1);
140
141 #ifdef CHAOS_PCC_DEBUG
142 #if 0
143                 map_changed = (t->current_space == as_attr && size == 2); /* XXX */
144 #else
145                 map_changed = 1;
146 #endif
147 #endif
148                 t->current_space = as_io;
149         }
150
151         /*
152          * access to IO space
153          */
154         if (size == 1) {
155                 /* Byte */
156                 unsigned char *bp = (unsigned char *)buf;
157
158 #ifdef CHAOS_DEBUG
159                 if (map_changed) {
160                         dummy_readbuf = readb(addr);
161                 }
162 #endif
163                 if (wr) {
164                         /* write Byte */
165                         while (nmemb--) {
166                                 writeb(*bp++, addr);
167                         }
168                 } else {
169                         /* read Byte */
170                         while (nmemb--) {
171                         *bp++ = readb(addr);
172                         }
173                 }
174         } else {
175                 /* Word */
176                 unsigned short *bp = (unsigned short *)buf;
177
178 #ifdef CHAOS_PCC_DEBUG
179                 if (map_changed) {
180                         dummy_readbuf = readw(addr);
181                 }
182 #endif
183                 if (wr) {
184                         /* write Word */
185                         while (nmemb--) {
186 #ifdef PCC_DEBUG_DBEX
187                                 if (_dbex) {
188                                         unsigned char *cp = (unsigned char *)bp;
189                                         unsigned short tmp;
190                                         tmp = cp[1] << 8 | cp[0];
191                                         writew(tmp, addr);
192                                         bp++;
193                                 } else
194 #endif
195                                 writew(*bp++, addr);
196                 }
197             } else {
198                 /* read Word */
199                 while (nmemb--) {
200 #ifdef  PCC_DEBUG_DBEX
201                                 if (_dbex) {
202                                         unsigned char *cp = (unsigned char *)bp;
203                                         unsigned short tmp;
204                                         tmp = readw(addr);
205                                         cp[0] = tmp & 0xff;
206                                         cp[1] = (tmp >> 8) & 0xff;
207                                         bp++;
208                                 } else
209 #endif
210                                 *bp++ = readw(addr);
211                 }
212             }
213         }
214
215 #if 1
216         /* addr is no longer used */
217         if ((addr = pcc_get(sock, PCIRC)) & PCIRC_BWERR) {
218           printk("m32r_pcc: BWERR detected : port 0x%04lx : iosize %dbit\n",
219                          port, size * 8);
220           pcc_set(sock, PCIRC, addr);
221         }
222 #endif
223         /*
224          * save state
225          */
226         t->last_iosize = size;
227         t->last_iodbex = need_ex;
228
229         /* Need lock ? */
230
231         spin_unlock_irqrestore(&pcc_lock,flags);
232
233         return;
234 }
235
236 void pcc_ioread(int sock, unsigned long port, void *buf, size_t size, size_t nmemb, int flag) {
237         pcc_iorw(sock, port, buf, size, nmemb, 0, flag);
238 }
239
240 void pcc_iowrite(int sock, unsigned long port, void *buf, size_t size, size_t nmemb, int flag) {
241     pcc_iorw(sock, port, buf, size, nmemb, 1, flag);
242 }
243
244 /*====================================================================*/
245
246 #define IS_REGISTERED           0x2000
247 #define IS_ALIVE                0x8000
248
249 typedef struct pcc_t {
250         char                    *name;
251         u_short                 flags;
252 } pcc_t;
253
254 static pcc_t pcc[] = {
255         { "xnux2", 0 }, { "xnux2", 0 },
256 };
257
258 static irqreturn_t pcc_interrupt(int, void *);
259
260 /*====================================================================*/
261
262 static struct timer_list poll_timer;
263
264 static unsigned int pcc_get(u_short sock, unsigned int reg)
265 {
266         return inl(socket[sock].base + reg);
267 }
268
269
270 static void pcc_set(u_short sock, unsigned int reg, unsigned int data)
271 {
272         outl(data, socket[sock].base + reg);
273 }
274
275 /*======================================================================
276
277         See if a card is present, powered up, in IO mode, and already
278         bound to a (non PC Card) Linux driver.  We leave these alone.
279
280         We make an exception for cards that seem to be serial devices.
281
282 ======================================================================*/
283
284 static int __init is_alive(u_short sock)
285 {
286         unsigned int stat;
287         unsigned int f;
288
289         stat = pcc_get(sock, PCIRC);
290         f = (stat & (PCIRC_CDIN1 | PCIRC_CDIN2)) >> 16;
291         if(!f){
292                 printk("m32r_pcc: No Card is detected at socket %d : stat = 0x%08x\n",stat,sock);
293                 return 0;
294         }
295         if(f!=3)
296                 printk("m32r_pcc: Insertion fail (%.8x) at socket %d\n",stat,sock);
297         else
298                 printk("m32r_pcc: Card is Inserted at socket %d(%.8x)\n",sock,stat);
299         return 0;
300 }
301
302 static void add_pcc_socket(ulong base, int irq, ulong mapaddr,
303                            unsigned int ioaddr)
304 {
305         pcc_socket_t *t = &socket[pcc_sockets];
306
307         /* add sockets */
308         t->ioaddr = ioaddr;
309         t->mapaddr = mapaddr;
310         t->base = base;
311 #ifdef CHAOS_PCC_DEBUG
312         t->flags = MAP_16BIT;
313 #else
314         t->flags = 0;
315 #endif
316         if (is_alive(pcc_sockets))
317                 t->flags |= IS_ALIVE;
318
319         /* add pcc */
320         if (t->base > 0) {
321                 request_region(t->base, 0x20, "m32r-pcc");
322         }
323
324         printk(KERN_INFO "  %s ", pcc[pcc_sockets].name);
325         printk("pcc at 0x%08lx\n", t->base);
326
327         /* Update socket interrupt information, capabilities */
328         t->socket.features |= (SS_CAP_PCCARD | SS_CAP_STATIC_MAP);
329         t->socket.map_size = M32R_PCC_MAPSIZE;
330         t->socket.io_offset = ioaddr;   /* use for io access offset */
331         t->socket.irq_mask = 0;
332         t->socket.pci_irq = 2 + pcc_sockets; /* XXX */
333
334         request_irq(irq, pcc_interrupt, 0, "m32r-pcc", pcc_interrupt);
335
336         pcc_sockets++;
337
338         return;
339 }
340
341
342 /*====================================================================*/
343
344 static irqreturn_t pcc_interrupt(int irq, void *dev)
345 {
346         int i, j, irc;
347         u_int events, active;
348         int handled = 0;
349
350         pr_debug("m32r_pcc: pcc_interrupt(%d)\n", irq);
351
352         for (j = 0; j < 20; j++) {
353                 active = 0;
354                 for (i = 0; i < pcc_sockets; i++) {
355                         if ((socket[i].cs_irq != irq) &&
356                                 (socket[i].socket.pci_irq != irq))
357                                 continue;
358                         handled = 1;
359                         irc = pcc_get(i, PCIRC);
360                         irc >>=16;
361                         pr_debug("m32r_pcc: interrupt: socket %d pcirc 0x%02x ",
362                                 i, irc);
363                         if (!irc)
364                                 continue;
365
366                         events = (irc) ? SS_DETECT : 0;
367                         events |= (pcc_get(i,PCCR) & PCCR_PCEN) ? SS_READY : 0;
368                         pr_debug("m32r_pcc: event 0x%02x\n", events);
369
370                         if (events)
371                                 pcmcia_parse_events(&socket[i].socket, events);
372
373                         active |= events;
374                         active = 0;
375                 }
376                 if (!active) break;
377         }
378         if (j == 20)
379                 printk(KERN_NOTICE "m32r-pcc: infinite loop in interrupt handler\n");
380
381         pr_debug("m32r_pcc: interrupt done\n");
382
383         return IRQ_RETVAL(handled);
384 } /* pcc_interrupt */
385
386 static void pcc_interrupt_wrapper(u_long data)
387 {
388         pcc_interrupt(0, NULL);
389         init_timer(&poll_timer);
390         poll_timer.expires = jiffies + poll_interval;
391         add_timer(&poll_timer);
392 }
393
394 /*====================================================================*/
395
396 static int _pcc_get_status(u_short sock, u_int *value)
397 {
398         u_int status;
399
400         status = pcc_get(sock,PCIRC);
401         *value = ((status & PCIRC_CDIN1) && (status & PCIRC_CDIN2))
402                 ? SS_DETECT : 0;
403
404         status = pcc_get(sock,PCCR);
405
406 #if 0
407         *value |= (status & PCCR_PCEN) ? SS_READY : 0;
408 #else
409         *value |= SS_READY; /* XXX: always */
410 #endif
411
412         status = pcc_get(sock,PCCSIGCR);
413         *value |= (status & PCCSIGCR_VEN) ? SS_POWERON : 0;
414
415         pr_debug("m32r_pcc: GetStatus(%d) = %#4.4x\n", sock, *value);
416         return 0;
417 } /* _get_status */
418
419 /*====================================================================*/
420
421 static int _pcc_set_socket(u_short sock, socket_state_t *state)
422 {
423         u_long reg = 0;
424
425         pr_debug("m32r_pcc: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
426                   "io_irq %d, csc_mask %#2.2x)", sock, state->flags,
427                   state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
428
429         if (state->Vcc) {
430                 /*
431                  * 5V only
432                  */
433                 if (state->Vcc == 50) {
434                         reg |= PCCSIGCR_VEN;
435                 } else {
436                         return -EINVAL;
437                 }
438         }
439
440         if (state->flags & SS_RESET) {
441                 pr_debug("m32r_pcc: :RESET\n");
442                 reg |= PCCSIGCR_CRST;
443         }
444         if (state->flags & SS_OUTPUT_ENA){
445                 pr_debug("m32r_pcc: :OUTPUT_ENA\n");
446                 /* bit clear */
447         } else {
448                 reg |= PCCSIGCR_SEN;
449         }
450
451         pcc_set(sock,PCCSIGCR,reg);
452
453         if(state->flags & SS_IOCARD){
454                 pr_debug("m32r_pcc: :IOCARD");
455         }
456         if (state->flags & SS_PWR_AUTO) {
457                 pr_debug("m32r_pcc: :PWR_AUTO");
458         }
459         if (state->csc_mask & SS_DETECT)
460                 pr_debug("m32r_pcc: :csc-SS_DETECT");
461         if (state->flags & SS_IOCARD) {
462                 if (state->csc_mask & SS_STSCHG)
463                         pr_debug("m32r_pcc: :STSCHG");
464         } else {
465                 if (state->csc_mask & SS_BATDEAD)
466                         pr_debug("m32r_pcc: :BATDEAD");
467                 if (state->csc_mask & SS_BATWARN)
468                         pr_debug("m32r_pcc: :BATWARN");
469                 if (state->csc_mask & SS_READY)
470                         pr_debug("m32r_pcc: :READY");
471         }
472         pr_debug("m32r_pcc: \n");
473         return 0;
474 } /* _set_socket */
475
476 /*====================================================================*/
477
478 static int _pcc_set_io_map(u_short sock, struct pccard_io_map *io)
479 {
480         u_char map;
481
482         pr_debug("m32r_pcc: SetIOMap(%d, %d, %#2.2x, %d ns, "
483                   "%#llx-%#llx)\n", sock, io->map, io->flags,
484                   io->speed, (unsigned long long)io->start,
485                   (unsigned long long)io->stop);
486         map = io->map;
487
488         return 0;
489 } /* _set_io_map */
490
491 /*====================================================================*/
492
493 static int _pcc_set_mem_map(u_short sock, struct pccard_mem_map *mem)
494 {
495
496         u_char map = mem->map;
497         u_long mode;
498         u_long addr;
499         pcc_socket_t *t = &socket[sock];
500 #ifdef CHAOS_PCC_DEBUG
501 #if 0
502         pcc_as_t last = t->current_space;
503 #endif
504 #endif
505
506         pr_debug("m32r_pcc: SetMemMap(%d, %d, %#2.2x, %d ns, "
507                  "%#llx,  %#x)\n", sock, map, mem->flags,
508                  mem->speed, (unsigned long long)mem->static_start,
509                  mem->card_start);
510
511         /*
512          * sanity check
513          */
514         if ((map > MAX_WIN) || (mem->card_start > 0x3ffffff)){
515                 return -EINVAL;
516         }
517
518         /*
519          * de-activate
520          */
521         if ((mem->flags & MAP_ACTIVE) == 0) {
522                 t->current_space = as_none;
523                 return 0;
524         }
525
526         /*
527          * Disable first
528          */
529         pcc_set(sock, PCCR, 0);
530
531         /*
532          * Set mode
533          */
534         if (mem->flags & MAP_ATTRIB) {
535                 mode = PCMOD_AS_ATTRIB | PCMOD_CBSZ;
536                 t->current_space = as_attr;
537         } else {
538                 mode = 0; /* common memory */
539                 t->current_space = as_comm;
540         }
541         pcc_set(sock, PCMOD, mode);
542
543         /*
544          * Set address
545          */
546         addr = t->mapaddr + (mem->card_start & M32R_PCC_MAPMASK);
547         pcc_set(sock, PCADR, addr);
548
549         mem->static_start = addr + mem->card_start;
550
551         /*
552          * Enable again
553          */
554         pcc_set(sock, PCCR, 1);
555
556 #ifdef CHAOS_PCC_DEBUG
557 #if 0
558         if (last != as_attr) {
559 #else
560         if (1) {
561 #endif
562                 dummy_readbuf = *(u_char *)(addr + KSEG1);
563         }
564 #endif
565
566         return 0;
567
568 } /* _set_mem_map */
569
570 #if 0 /* driver model ordering issue */
571 /*======================================================================
572
573         Routines for accessing socket information and register dumps via
574         /proc/bus/pccard/...
575
576 ======================================================================*/
577
578 static ssize_t show_info(struct class_device *class_dev, char *buf)
579 {
580         pcc_socket_t *s = container_of(class_dev, struct pcc_socket,
581                 socket.dev);
582
583         return sprintf(buf, "type:     %s\nbase addr:    0x%08lx\n",
584                 pcc[s->type].name, s->base);
585 }
586
587 static ssize_t show_exca(struct class_device *class_dev, char *buf)
588 {
589         /* FIXME */
590
591         return 0;
592 }
593
594 static CLASS_DEVICE_ATTR(info, S_IRUGO, show_info, NULL);
595 static CLASS_DEVICE_ATTR(exca, S_IRUGO, show_exca, NULL);
596 #endif
597
598 /*====================================================================*/
599
600 /* this is horribly ugly... proper locking needs to be done here at
601  * some time... */
602 #define LOCKED(x) do {                                  \
603         int retval;                                     \
604         unsigned long flags;                            \
605         spin_lock_irqsave(&pcc_lock, flags);            \
606         retval = x;                                     \
607         spin_unlock_irqrestore(&pcc_lock, flags);       \
608         return retval;                                  \
609 } while (0)
610
611
612 static int pcc_get_status(struct pcmcia_socket *s, u_int *value)
613 {
614         unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
615
616         if (socket[sock].flags & IS_ALIVE) {
617                 *value = 0;
618                 return -EINVAL;
619         }
620         LOCKED(_pcc_get_status(sock, value));
621 }
622
623 static int pcc_set_socket(struct pcmcia_socket *s, socket_state_t *state)
624 {
625         unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
626
627         if (socket[sock].flags & IS_ALIVE)
628                 return -EINVAL;
629
630         LOCKED(_pcc_set_socket(sock, state));
631 }
632
633 static int pcc_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io)
634 {
635         unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
636
637         if (socket[sock].flags & IS_ALIVE)
638                 return -EINVAL;
639         LOCKED(_pcc_set_io_map(sock, io));
640 }
641
642 static int pcc_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *mem)
643 {
644         unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
645
646         if (socket[sock].flags & IS_ALIVE)
647                 return -EINVAL;
648         LOCKED(_pcc_set_mem_map(sock, mem));
649 }
650
651 static int pcc_init(struct pcmcia_socket *s)
652 {
653         pr_debug("m32r_pcc: init call\n");
654         return 0;
655 }
656
657 static struct pccard_operations pcc_operations = {
658         .init                   = pcc_init,
659         .get_status             = pcc_get_status,
660         .set_socket             = pcc_set_socket,
661         .set_io_map             = pcc_set_io_map,
662         .set_mem_map            = pcc_set_mem_map,
663 };
664
665 /*====================================================================*/
666
667 static struct platform_driver pcc_driver = {
668         .driver = {
669                 .name           = "pcc",
670                 .owner          = THIS_MODULE,
671         },
672 };
673
674 static struct platform_device pcc_device = {
675         .name = "pcc",
676         .id = 0,
677 };
678
679 /*====================================================================*/
680
681 static int __init init_m32r_pcc(void)
682 {
683         int i, ret;
684
685         ret = platform_driver_register(&pcc_driver);
686         if (ret)
687                 return ret;
688
689         ret = platform_device_register(&pcc_device);
690         if (ret){
691                 platform_driver_unregister(&pcc_driver);
692                 return ret;
693         }
694
695         printk(KERN_INFO "m32r PCC probe:\n");
696
697         pcc_sockets = 0;
698
699         add_pcc_socket(M32R_PCC0_BASE, PCC0_IRQ, M32R_PCC0_MAPBASE, 0x1000);
700
701 #ifdef CONFIG_M32RPCC_SLOT2
702         add_pcc_socket(M32R_PCC1_BASE, PCC1_IRQ, M32R_PCC1_MAPBASE, 0x2000);
703 #endif
704
705         if (pcc_sockets == 0) {
706                 printk("socket is not found.\n");
707                 platform_device_unregister(&pcc_device);
708                 platform_driver_unregister(&pcc_driver);
709                 return -ENODEV;
710         }
711
712         /* Set up interrupt handler(s) */
713
714         for (i = 0 ; i < pcc_sockets ; i++) {
715                 socket[i].socket.dev.parent = &pcc_device.dev;
716                 socket[i].socket.ops = &pcc_operations;
717                 socket[i].socket.resource_ops = &pccard_static_ops;
718                 socket[i].socket.owner = THIS_MODULE;
719                 socket[i].number = i;
720                 ret = pcmcia_register_socket(&socket[i].socket);
721                 if (!ret)
722                         socket[i].flags |= IS_REGISTERED;
723
724 #if 0   /* driver model ordering issue */
725                 class_device_create_file(&socket[i].socket.dev,
726                                          &class_device_attr_info);
727                 class_device_create_file(&socket[i].socket.dev,
728                                          &class_device_attr_exca);
729 #endif
730         }
731
732         /* Finally, schedule a polling interrupt */
733         if (poll_interval != 0) {
734                 poll_timer.function = pcc_interrupt_wrapper;
735                 poll_timer.data = 0;
736                 init_timer(&poll_timer);
737                 poll_timer.expires = jiffies + poll_interval;
738                 add_timer(&poll_timer);
739         }
740
741         return 0;
742 } /* init_m32r_pcc */
743
744 static void __exit exit_m32r_pcc(void)
745 {
746         int i;
747
748         for (i = 0; i < pcc_sockets; i++)
749                 if (socket[i].flags & IS_REGISTERED)
750                         pcmcia_unregister_socket(&socket[i].socket);
751
752         platform_device_unregister(&pcc_device);
753         if (poll_interval != 0)
754                 del_timer_sync(&poll_timer);
755
756         platform_driver_unregister(&pcc_driver);
757 } /* exit_m32r_pcc */
758
759 module_init(init_m32r_pcc);
760 module_exit(exit_m32r_pcc);
761 MODULE_LICENSE("Dual MPL/GPL");
762 /*====================================================================*/