/* $Id: avm_a1p.c,v 2.9.2.5 2004/01/24 20:47:19 keil Exp $
 *
 * low level stuff for the following AVM cards:
 * A1 PCMCIA
 * FRITZ!Card PCMCIA
 * FRITZ!Card PCMCIA 2.0
 *
 * Author       Carsten Paeth
 * Copyright    by Carsten Paeth     <calle@calle.de>
 *
 * This software may be used and distributed according to the terms
 * of the GNU General Public License, incorporated herein by reference.
 *
 */

#include <linux/init.h>
#include "hisax.h"
#include "isac.h"
#include "hscx.h"
#include "isdnl1.h"

/* register offsets */
#define ADDRREG_OFFSET		0x02
#define DATAREG_OFFSET		0x03
#define ASL0_OFFSET		0x04
#define ASL1_OFFSET		0x05
#define MODREG_OFFSET		0x06
#define VERREG_OFFSET		0x07

/* address offsets */
#define ISAC_FIFO_OFFSET	0x00
#define ISAC_REG_OFFSET		0x20
#define HSCX_CH_DIFF		0x40
#define HSCX_FIFO_OFFSET	0x80
#define HSCX_REG_OFFSET		0xa0

/* read bits ASL0 */
#define	 ASL0_R_TIMER		0x10 /* active low */
#define	 ASL0_R_ISAC		0x20 /* active low */
#define	 ASL0_R_HSCX		0x40 /* active low */
#define	 ASL0_R_TESTBIT		0x80
#define  ASL0_R_IRQPENDING	(ASL0_R_ISAC|ASL0_R_HSCX|ASL0_R_TIMER)

/* write bits ASL0 */
#define	 ASL0_W_RESET		0x01
#define	 ASL0_W_TDISABLE	0x02
#define	 ASL0_W_TRESET		0x04
#define	 ASL0_W_IRQENABLE	0x08
#define	 ASL0_W_TESTBIT		0x80

/* write bits ASL1 */
#define	 ASL1_W_LED0		0x10
#define	 ASL1_W_LED1		0x20
#define	 ASL1_W_ENABLE_S0	0xC0
 
#define byteout(addr,val) outb(val,addr)
#define bytein(addr) inb(addr)

static const char *avm_revision = "$Revision: 2.9.2.5 $";

static inline u_char
ReadISAC(struct IsdnCardState *cs, u_char offset)
{
        u_char ret;

        offset -= 0x20;
        byteout(cs->hw.avm.cfg_reg+ADDRREG_OFFSET,ISAC_REG_OFFSET+offset);
	ret = bytein(cs->hw.avm.cfg_reg+DATAREG_OFFSET);
	return ret;
}

static inline void
WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
{
        offset -= 0x20;
        byteout(cs->hw.avm.cfg_reg+ADDRREG_OFFSET,ISAC_REG_OFFSET+offset);
	byteout(cs->hw.avm.cfg_reg+DATAREG_OFFSET, value);
}

static inline void
ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
{
	byteout(cs->hw.avm.cfg_reg+ADDRREG_OFFSET,ISAC_FIFO_OFFSET);
	insb(cs->hw.avm.cfg_reg+DATAREG_OFFSET, data, size);
}

static inline void
WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
{
	byteout(cs->hw.avm.cfg_reg+ADDRREG_OFFSET,ISAC_FIFO_OFFSET);
	outsb(cs->hw.avm.cfg_reg+DATAREG_OFFSET, data, size);
}

static inline u_char
ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset)
{
	u_char ret;

        offset -= 0x20;
	byteout(cs->hw.avm.cfg_reg+ADDRREG_OFFSET,
			HSCX_REG_OFFSET+hscx*HSCX_CH_DIFF+offset);
	ret = bytein(cs->hw.avm.cfg_reg+DATAREG_OFFSET);
	return ret;
}

static inline void
WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
{
        offset -= 0x20;
	byteout(cs->hw.avm.cfg_reg+ADDRREG_OFFSET,
			HSCX_REG_OFFSET+hscx*HSCX_CH_DIFF+offset);
	byteout(cs->hw.avm.cfg_reg+DATAREG_OFFSET, value);
}

static inline void
ReadHSCXfifo(struct IsdnCardState *cs, int hscx, u_char * data, int size)
{
	byteout(cs->hw.avm.cfg_reg+ADDRREG_OFFSET,
			HSCX_FIFO_OFFSET+hscx*HSCX_CH_DIFF);
	insb(cs->hw.avm.cfg_reg+DATAREG_OFFSET, data, size);
}

static inline void
WriteHSCXfifo(struct IsdnCardState *cs, int hscx, u_char * data, int size)
{
	byteout(cs->hw.avm.cfg_reg+ADDRREG_OFFSET,
			HSCX_FIFO_OFFSET+hscx*HSCX_CH_DIFF);
	outsb(cs->hw.avm.cfg_reg+DATAREG_OFFSET, data, size);
}

/*
 * fast interrupt HSCX stuff goes here
 */

#define READHSCX(cs, nr, reg) ReadHSCX(cs, nr, reg)
#define WRITEHSCX(cs, nr, reg, data) WriteHSCX(cs, nr, reg, data)
#define READHSCXFIFO(cs, nr, ptr, cnt) ReadHSCXfifo(cs, nr, ptr, cnt) 
#define WRITEHSCXFIFO(cs, nr, ptr, cnt) WriteHSCXfifo(cs, nr, ptr, cnt)

#include "hscx_irq.c"

static irqreturn_t
avm_a1p_interrupt(int intno, void *dev_id)
{
	struct IsdnCardState *cs = dev_id;
	u_char val, sval;
	u_long flags;

	spin_lock_irqsave(&cs->lock, flags);
	while ((sval = (~bytein(cs->hw.avm.cfg_reg+ASL0_OFFSET) & ASL0_R_IRQPENDING))) {
		if (cs->debug & L1_DEB_INTSTAT)
			debugl1(cs, "avm IntStatus %x", sval);
		if (sval & ASL0_R_HSCX) {
                        val = ReadHSCX(cs, 1, HSCX_ISTA);
			if (val)
				hscx_int_main(cs, val);
		}
		if (sval & ASL0_R_ISAC) {
			val = ReadISAC(cs, ISAC_ISTA);
			if (val)
				isac_interrupt(cs, val);
		}
	}
	WriteHSCX(cs, 0, HSCX_MASK, 0xff);
	WriteHSCX(cs, 1, HSCX_MASK, 0xff);
	WriteISAC(cs, ISAC_MASK, 0xff);
	WriteISAC(cs, ISAC_MASK, 0x00);
	WriteHSCX(cs, 0, HSCX_MASK, 0x00);
	WriteHSCX(cs, 1, HSCX_MASK, 0x00);
	spin_unlock_irqrestore(&cs->lock, flags);
	return IRQ_HANDLED;
}

static int
AVM_card_msg(struct IsdnCardState *cs, int mt, void *arg)
{
	u_long flags;

	switch (mt) {
		case CARD_RESET:
			spin_lock_irqsave(&cs->lock, flags);
			byteout(cs->hw.avm.cfg_reg+ASL0_OFFSET,0x00);
			HZDELAY(HZ / 5 + 1);
			byteout(cs->hw.avm.cfg_reg+ASL0_OFFSET,ASL0_W_RESET);
			HZDELAY(HZ / 5 + 1);
			byteout(cs->hw.avm.cfg_reg+ASL0_OFFSET,0x00);
			spin_unlock_irqrestore(&cs->lock, flags);
			return 0;

		case CARD_RELEASE:
			/* free_irq is done in HiSax_closecard(). */
		        /* free_irq(cs->irq, cs); */
			return 0;

		case CARD_INIT:
			spin_lock_irqsave(&cs->lock, flags);
			byteout(cs->hw.avm.cfg_reg+ASL0_OFFSET,ASL0_W_TDISABLE|ASL0_W_TRESET|ASL0_W_IRQENABLE);
			clear_pending_isac_ints(cs);
			clear_pending_hscx_ints(cs);
			inithscxisac(cs, 1);
			inithscxisac(cs, 2);
			spin_unlock_irqrestore(&cs->lock, flags);
			return 0;

		case CARD_TEST:
			/* we really don't need it for the PCMCIA Version */
			return 0;

		default:
			/* all card drivers ignore others, so we do the same */
			return 0;
	}
	return 0;
}

int __devinit setup_avm_a1_pcmcia(struct IsdnCard *card)
{
	u_char model, vers;
	struct IsdnCardState *cs = card->cs;
	char tmp[64];


	strcpy(tmp, avm_revision);
	printk(KERN_INFO "HiSax: AVM A1 PCMCIA driver Rev. %s\n",
						 HiSax_getrev(tmp));
	if (cs->typ != ISDN_CTYPE_A1_PCMCIA)
		return (0);

	cs->hw.avm.cfg_reg = card->para[1];
	cs->irq = card->para[0];


	byteout(cs->hw.avm.cfg_reg+ASL1_OFFSET, ASL1_W_ENABLE_S0);
	byteout(cs->hw.avm.cfg_reg+ASL0_OFFSET,0x00);
	HZDELAY(HZ / 5 + 1);
	byteout(cs->hw.avm.cfg_reg+ASL0_OFFSET,ASL0_W_RESET);
	HZDELAY(HZ / 5 + 1);
	byteout(cs->hw.avm.cfg_reg+ASL0_OFFSET,0x00);

	byteout(cs->hw.avm.cfg_reg+ASL0_OFFSET, ASL0_W_TDISABLE|ASL0_W_TRESET);

	model = bytein(cs->hw.avm.cfg_reg+MODREG_OFFSET);
	vers = bytein(cs->hw.avm.cfg_reg+VERREG_OFFSET);

	printk(KERN_INFO "AVM A1 PCMCIA: io 0x%x irq %d model %d version %d\n",
				cs->hw.avm.cfg_reg, cs->irq, model, vers);

	setup_isac(cs);
	cs->readisac = &ReadISAC;
	cs->writeisac = &WriteISAC;
	cs->readisacfifo = &ReadISACfifo;
	cs->writeisacfifo = &WriteISACfifo;
	cs->BC_Read_Reg = &ReadHSCX;
	cs->BC_Write_Reg = &WriteHSCX;
	cs->BC_Send_Data = &hscx_fill_fifo;
	cs->cardmsg = &AVM_card_msg;
	cs->irq_flags = IRQF_SHARED;
	cs->irq_func = &avm_a1p_interrupt;

	ISACVersion(cs, "AVM A1 PCMCIA:");
	if (HscxVersion(cs, "AVM A1 PCMCIA:")) {
		printk(KERN_WARNING
		       "AVM A1 PCMCIA: wrong HSCX versions check IO address\n");
		return (0);
	}
	return (1);
}
