/*
 *
 * Alchemy Semi Db1x00 boards specific pcmcia routines.
 *
 * Copyright 2002 MontaVista Software Inc.
 * Author: MontaVista Software, Inc.
 *         	ppopov@mvista.com or source@mvista.com
 *
 * Copyright 2004 Pete Popov, updated the driver to 2.6.
 * Followed the sa11xx API and largely copied many of the hardware
 * independent functions.
 *
 * ########################################################################
 *
 *  This program is free software; you can distribute it and/or modify it
 *  under the terms of the GNU General Public License (Version 2) as
 *  published by the Free Software Foundation.
 *
 *  This program is distributed in the hope it will be useful, but WITHOUT
 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 *  for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
 *
 * ########################################################################
 *
 *
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/device.h>
#include <linux/init.h>

#include <asm/irq.h>
#include <asm/signal.h>
#include <asm/mach-au1x00/au1000.h>

#if defined(CONFIG_MIPS_DB1200)
	#include <db1200.h>
#elif defined(CONFIG_MIPS_PB1200)
	#include <pb1200.h>
#else
	#include <asm/mach-db1x00/db1x00.h>
	static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
#endif

#include "au1000_generic.h"

#if 0
#define debug(x,args...) printk(KERN_DEBUG "%s: " x, __func__ , ##args)
#else
#define debug(x,args...)
#endif


struct au1000_pcmcia_socket au1000_pcmcia_socket[PCMCIA_NUM_SOCKS];
extern int au1x00_pcmcia_socket_probe(struct device *, struct pcmcia_low_level *, int, int);

static int db1x00_pcmcia_hw_init(struct au1000_pcmcia_socket *skt)
{
#ifdef CONFIG_MIPS_DB1550
	skt->irq = skt->nr ? AU1000_GPIO_5 : AU1000_GPIO_3;
#elif defined(CONFIG_MIPS_DB1200) || defined(CONFIG_MIPS_PB1200)
	skt->irq = skt->nr ? BOARD_PC1_INT : BOARD_PC0_INT;
#else
	skt->irq = skt->nr ? AU1000_GPIO_5 : AU1000_GPIO_2;
#endif
	return 0;
}

static void db1x00_pcmcia_shutdown(struct au1000_pcmcia_socket *skt)
{
	bcsr->pcmcia = 0; /* turn off power */
	au_sync_delay(2);
}

static void
db1x00_pcmcia_socket_state(struct au1000_pcmcia_socket *skt, struct pcmcia_state *state)
{
	u32 inserted;
	unsigned char vs;

	state->ready = 0;
	state->vs_Xv = 0;
	state->vs_3v = 0;
	state->detect = 0;

	switch (skt->nr) {
	case 0:
		vs = bcsr->status & 0x3;
#if defined(CONFIG_MIPS_DB1200) || defined(CONFIG_MIPS_PB1200)
		inserted = BOARD_CARD_INSERTED(0);
#else
		inserted = !(bcsr->status & (1<<4));
#endif
		break;
	case 1:
		vs = (bcsr->status & 0xC)>>2;
#if defined(CONFIG_MIPS_DB1200) || defined(CONFIG_MIPS_PB1200)
		inserted = BOARD_CARD_INSERTED(1);
#else
		inserted = !(bcsr->status & (1<<5));
#endif
		break;
	default:/* should never happen */
		return;
	}

	if (inserted)
		debug("db1x00 socket %d: inserted %d, vs %d pcmcia %x\n",
				skt->nr, inserted, vs, bcsr->pcmcia);

	if (inserted) {
		switch (vs) {
			case 0:
			case 2:
				state->vs_3v=1;
				break;
			case 3: /* 5V */
				break;
			default:
				/* return without setting 'detect' */
				printk(KERN_ERR "db1x00 bad VS (%d)\n",
						vs);
		}
		state->detect = 1;
		state->ready = 1;
	}
	else {
		/* if the card was previously inserted and then ejected,
		 * we should turn off power to it
		 */
		if ((skt->nr == 0) && (bcsr->pcmcia & BCSR_PCMCIA_PC0RST)) {
			bcsr->pcmcia &= ~(BCSR_PCMCIA_PC0RST |
					BCSR_PCMCIA_PC0DRVEN |
					BCSR_PCMCIA_PC0VPP |
					BCSR_PCMCIA_PC0VCC);
			au_sync_delay(10);
		}
		else if ((skt->nr == 1) && bcsr->pcmcia & BCSR_PCMCIA_PC1RST) {
			bcsr->pcmcia &= ~(BCSR_PCMCIA_PC1RST |
					BCSR_PCMCIA_PC1DRVEN |
					BCSR_PCMCIA_PC1VPP |
					BCSR_PCMCIA_PC1VCC);
			au_sync_delay(10);
		}
	}

	state->bvd1=1;
	state->bvd2=1;
	state->wrprot=0;
}

static int
db1x00_pcmcia_configure_socket(struct au1000_pcmcia_socket *skt, struct socket_state_t *state)
{
	u16 pwr;
	int sock = skt->nr;

	debug("config_skt %d Vcc %dV Vpp %dV, reset %d\n",
			sock, state->Vcc, state->Vpp,
			state->flags & SS_RESET);

	/* pcmcia reg was set to zero at init time. Be careful when
	 * initializing a socket not to wipe out the settings of the
	 * other socket.
	 */
	pwr = bcsr->pcmcia;
	pwr &= ~(0xf << sock*8); /* clear voltage settings */

	state->Vpp = 0;
	switch(state->Vcc){
		case 0:  /* Vcc 0 */
			pwr |= SET_VCC_VPP(0,0,sock);
			break;
		case 50: /* Vcc 5V */
			switch(state->Vpp) {
				case 0:
					pwr |= SET_VCC_VPP(2,0,sock);
					break;
				case 50:
					pwr |= SET_VCC_VPP(2,1,sock);
					break;
				case 12:
					pwr |= SET_VCC_VPP(2,2,sock);
					break;
				case 33:
				default:
					pwr |= SET_VCC_VPP(0,0,sock);
					printk("%s: bad Vcc/Vpp (%d:%d)\n",
							__FUNCTION__,
							state->Vcc,
							state->Vpp);
					break;
			}
			break;
		case 33: /* Vcc 3.3V */
			switch(state->Vpp) {
				case 0:
					pwr |= SET_VCC_VPP(1,0,sock);
					break;
				case 12:
					pwr |= SET_VCC_VPP(1,2,sock);
					break;
				case 33:
					pwr |= SET_VCC_VPP(1,1,sock);
					break;
				case 50:
				default:
					pwr |= SET_VCC_VPP(0,0,sock);
					printk("%s: bad Vcc/Vpp (%d:%d)\n",
							__FUNCTION__,
							state->Vcc,
							state->Vpp);
					break;
			}
			break;
		default: /* what's this ? */
			pwr |= SET_VCC_VPP(0,0,sock);
			printk(KERN_ERR "%s: bad Vcc %d\n",
					__FUNCTION__, state->Vcc);
			break;
	}

	bcsr->pcmcia = pwr;
	au_sync_delay(300);

	if (sock == 0) {
		if (!(state->flags & SS_RESET)) {
			pwr |= BCSR_PCMCIA_PC0DRVEN;
			bcsr->pcmcia = pwr;
			au_sync_delay(300);
			pwr |= BCSR_PCMCIA_PC0RST;
			bcsr->pcmcia = pwr;
			au_sync_delay(100);
		}
		else {
			pwr &= ~(BCSR_PCMCIA_PC0RST | BCSR_PCMCIA_PC0DRVEN);
			bcsr->pcmcia = pwr;
			au_sync_delay(100);
		}
	}
	else {
		if (!(state->flags & SS_RESET)) {
			pwr |= BCSR_PCMCIA_PC1DRVEN;
			bcsr->pcmcia = pwr;
			au_sync_delay(300);
			pwr |= BCSR_PCMCIA_PC1RST;
			bcsr->pcmcia = pwr;
			au_sync_delay(100);
		}
		else {
			pwr &= ~(BCSR_PCMCIA_PC1RST | BCSR_PCMCIA_PC1DRVEN);
			bcsr->pcmcia = pwr;
			au_sync_delay(100);
		}
	}
	return 0;
}

/*
 * Enable card status IRQs on (re-)initialisation.  This can
 * be called at initialisation, power management event, or
 * pcmcia event.
 */
void db1x00_socket_init(struct au1000_pcmcia_socket *skt)
{
	/* nothing to do for now */
}

/*
 * Disable card status IRQs and PCMCIA bus on suspend.
 */
void db1x00_socket_suspend(struct au1000_pcmcia_socket *skt)
{
	/* nothing to do for now */
}

struct pcmcia_low_level db1x00_pcmcia_ops = {
	.owner			= THIS_MODULE,

	.hw_init 		= db1x00_pcmcia_hw_init,
	.hw_shutdown		= db1x00_pcmcia_shutdown,

	.socket_state		= db1x00_pcmcia_socket_state,
	.configure_socket	= db1x00_pcmcia_configure_socket,

	.socket_init		= db1x00_socket_init,
	.socket_suspend		= db1x00_socket_suspend
};

int au1x_board_init(struct device *dev)
{
	int ret = -ENODEV;
	bcsr->pcmcia = 0; /* turn off power, if it's not already off */
	au_sync_delay(2);
	ret = au1x00_pcmcia_socket_probe(dev, &db1x00_pcmcia_ops, 0, 2);
	return ret;
}
