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