/* $Id: sportster.c,v 1.16.2.4 2004/01/13 23:48:39 keil Exp $
 *
 * low level stuff for USR Sportster internal TA
 *
 * Author       Karsten Keil
 * Copyright    by Karsten Keil      <keil@isdn4linux.de>
 *
 * This software may be used and distributed according to the terms
 * of the GNU General Public License, incorporated herein by reference.
 *
 * Thanks to Christian "naddy" Weisgerber (3Com, US Robotics) for documentation
 *
 *
 */
#include <linux/init.h>
#include "hisax.h"
#include "isac.h"
#include "hscx.h"
#include "isdnl1.h"

static const char *sportster_revision = "$Revision: 1.16.2.4 $";

#define byteout(addr, val) outb(val, addr)
#define bytein(addr) inb(addr)

#define	 SPORTSTER_ISAC		0xC000
#define	 SPORTSTER_HSCXA	0x0000
#define	 SPORTSTER_HSCXB	0x4000
#define	 SPORTSTER_RES_IRQ	0x8000
#define	 SPORTSTER_RESET	0x80
#define	 SPORTSTER_INTE		0x40

static inline int
calc_off(unsigned int base, unsigned int off)
{
	return (base + ((off & 0xfc) << 8) + ((off & 3) << 1));
}

static inline void
read_fifo(unsigned int adr, u_char *data, int size)
{
	insb(adr, data, size);
}

static void
write_fifo(unsigned int adr, u_char *data, int size)
{
	outsb(adr, data, size);
}

/* Interface functions */

static u_char
ReadISAC(struct IsdnCardState *cs, u_char offset)
{
	return (bytein(calc_off(cs->hw.spt.isac, offset)));
}

static void
WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
{
	byteout(calc_off(cs->hw.spt.isac, offset), value);
}

static void
ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size)
{
	read_fifo(cs->hw.spt.isac, data, size);
}

static void
WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size)
{
	write_fifo(cs->hw.spt.isac, data, size);
}

static u_char
ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset)
{
	return (bytein(calc_off(cs->hw.spt.hscx[hscx], offset)));
}

static void
WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
{
	byteout(calc_off(cs->hw.spt.hscx[hscx], offset), value);
}

/*
 * fast interrupt HSCX stuff goes here
 */

#define READHSCX(cs, nr, reg) bytein(calc_off(cs->hw.spt.hscx[nr], reg))
#define WRITEHSCX(cs, nr, reg, data) byteout(calc_off(cs->hw.spt.hscx[nr], reg), data)
#define READHSCXFIFO(cs, nr, ptr, cnt) read_fifo(cs->hw.spt.hscx[nr], ptr, cnt)
#define WRITEHSCXFIFO(cs, nr, ptr, cnt) write_fifo(cs->hw.spt.hscx[nr], ptr, cnt)

#include "hscx_irq.c"

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

	spin_lock_irqsave(&cs->lock, flags);
	val = READHSCX(cs, 1, HSCX_ISTA);
Start_HSCX:
	if (val)
		hscx_int_main(cs, val);
	val = ReadISAC(cs, ISAC_ISTA);
Start_ISAC:
	if (val)
		isac_interrupt(cs, val);
	val = READHSCX(cs, 1, HSCX_ISTA);
	if (val) {
		if (cs->debug & L1_DEB_HSCX)
			debugl1(cs, "HSCX IntStat after IntRoutine");
		goto Start_HSCX;
	}
	val = ReadISAC(cs, ISAC_ISTA);
	if (val) {
		if (cs->debug & L1_DEB_ISAC)
			debugl1(cs, "ISAC IntStat after IntRoutine");
		goto Start_ISAC;
	}
	/* get a new irq impulse if there any pending */
	bytein(cs->hw.spt.cfg_reg + SPORTSTER_RES_IRQ + 1);
	spin_unlock_irqrestore(&cs->lock, flags);
	return IRQ_HANDLED;
}

static void
release_io_sportster(struct IsdnCardState *cs)
{
	int i, adr;

	byteout(cs->hw.spt.cfg_reg + SPORTSTER_RES_IRQ, 0);
	for (i = 0; i < 64; i++) {
		adr = cs->hw.spt.cfg_reg + i * 1024;
		release_region(adr, 8);
	}
}

static void
reset_sportster(struct IsdnCardState *cs)
{
	cs->hw.spt.res_irq |= SPORTSTER_RESET; /* Reset On */
	byteout(cs->hw.spt.cfg_reg + SPORTSTER_RES_IRQ, cs->hw.spt.res_irq);
	mdelay(10);
	cs->hw.spt.res_irq &= ~SPORTSTER_RESET; /* Reset Off */
	byteout(cs->hw.spt.cfg_reg + SPORTSTER_RES_IRQ, cs->hw.spt.res_irq);
	mdelay(10);
}

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

	switch (mt) {
	case CARD_RESET:
		spin_lock_irqsave(&cs->lock, flags);
		reset_sportster(cs);
		spin_unlock_irqrestore(&cs->lock, flags);
		return (0);
	case CARD_RELEASE:
		release_io_sportster(cs);
		return (0);
	case CARD_INIT:
		spin_lock_irqsave(&cs->lock, flags);
		reset_sportster(cs);
		inithscxisac(cs, 1);
		cs->hw.spt.res_irq |= SPORTSTER_INTE; /* IRQ On */
		byteout(cs->hw.spt.cfg_reg + SPORTSTER_RES_IRQ, cs->hw.spt.res_irq);
		inithscxisac(cs, 2);
		spin_unlock_irqrestore(&cs->lock, flags);
		return (0);
	case CARD_TEST:
		return (0);
	}
	return (0);
}

static int __devinit
get_io_range(struct IsdnCardState *cs)
{
	int i, j, adr;

	for (i = 0; i < 64; i++) {
		adr = cs->hw.spt.cfg_reg + i * 1024;
		if (!request_region(adr, 8, "sportster")) {
			printk(KERN_WARNING "HiSax: USR Sportster config port "
			       "%x-%x already in use\n",
			       adr, adr + 8);
			break;
		}
	}
	if (i == 64)
		return (1);
	else {
		for (j = 0; j < i; j++) {
			adr = cs->hw.spt.cfg_reg + j * 1024;
			release_region(adr, 8);
		}
		return (0);
	}
}

int __devinit
setup_sportster(struct IsdnCard *card)
{
	struct IsdnCardState *cs = card->cs;
	char tmp[64];

	strcpy(tmp, sportster_revision);
	printk(KERN_INFO "HiSax: USR Sportster driver Rev. %s\n", HiSax_getrev(tmp));
	if (cs->typ != ISDN_CTYPE_SPORTSTER)
		return (0);

	cs->hw.spt.cfg_reg = card->para[1];
	cs->irq = card->para[0];
	if (!get_io_range(cs))
		return (0);
	cs->hw.spt.isac = cs->hw.spt.cfg_reg + SPORTSTER_ISAC;
	cs->hw.spt.hscx[0] = cs->hw.spt.cfg_reg + SPORTSTER_HSCXA;
	cs->hw.spt.hscx[1] = cs->hw.spt.cfg_reg + SPORTSTER_HSCXB;

	switch (cs->irq) {
	case 5:	cs->hw.spt.res_irq = 1;
		break;
	case 7:	cs->hw.spt.res_irq = 2;
		break;
	case 10:cs->hw.spt.res_irq = 3;
		break;
	case 11:cs->hw.spt.res_irq = 4;
		break;
	case 12:cs->hw.spt.res_irq = 5;
		break;
	case 14:cs->hw.spt.res_irq = 6;
		break;
	case 15:cs->hw.spt.res_irq = 7;
		break;
	default:release_io_sportster(cs);
		printk(KERN_WARNING "Sportster: wrong IRQ\n");
		return (0);
	}
	printk(KERN_INFO "HiSax: USR Sportster config irq:%d cfg:0x%X\n",
	       cs->irq, cs->hw.spt.cfg_reg);
	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 = &Sportster_card_msg;
	cs->irq_func = &sportster_interrupt;
	ISACVersion(cs, "Sportster:");
	if (HscxVersion(cs, "Sportster:")) {
		printk(KERN_WARNING
		       "Sportster: wrong HSCX versions check IO address\n");
		release_io_sportster(cs);
		return (0);
	}
	return (1);
}
