/*
 * speedfax.c	low level stuff for Sedlbauer Speedfax+ cards
 *		based on the ISAR DSP
 *		Thanks to Sedlbauer AG for informations and HW
 *
 * Author       Karsten Keil <keil@isdn4linux.de>
 *
 * Copyright 2009  by Karsten Keil <keil@isdn4linux.de>
 *
 * This program is free software; you can redistribute 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 that 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/mISDNhw.h>
#include <linux/firmware.h>
#include "ipac.h"
#include "isar.h"

#define SPEEDFAX_REV	"2.0"

#define PCI_SUBVENDOR_SPEEDFAX_PYRAMID	0x51
#define PCI_SUBVENDOR_SPEEDFAX_PCI	0x54
#define PCI_SUB_ID_SEDLBAUER		0x01

#define SFAX_PCI_ADDR		0xc8
#define SFAX_PCI_ISAC		0xd0
#define SFAX_PCI_ISAR		0xe0

/* TIGER 100 Registers */

#define TIGER_RESET_ADDR	0x00
#define TIGER_EXTERN_RESET_ON	0x01
#define TIGER_EXTERN_RESET_OFF	0x00
#define TIGER_AUX_CTRL		0x02
#define TIGER_AUX_DATA		0x03
#define TIGER_AUX_IRQMASK	0x05
#define TIGER_AUX_STATUS	0x07

/* Tiger AUX BITs */
#define SFAX_AUX_IOMASK		0xdd	/* 1 and 5 are inputs */
#define SFAX_ISAR_RESET_BIT_OFF 0x00
#define SFAX_ISAR_RESET_BIT_ON	0x01
#define SFAX_TIGER_IRQ_BIT	0x02
#define SFAX_LED1_BIT		0x08
#define SFAX_LED2_BIT		0x10

#define SFAX_PCI_RESET_ON	(SFAX_ISAR_RESET_BIT_ON)
#define SFAX_PCI_RESET_OFF	(SFAX_LED1_BIT | SFAX_LED2_BIT)

static int sfax_cnt;
static u32 debug;
static u32 irqloops = 4;

struct sfax_hw {
	struct list_head	list;
	struct pci_dev		*pdev;
	char			name[MISDN_MAX_IDLEN];
	u32			irq;
	u32			irqcnt;
	u32			cfg;
	struct _ioport		p_isac;
	struct _ioport		p_isar;
	u8			aux_data;
	spinlock_t		lock;	/* HW access lock */
	struct isac_hw		isac;
	struct isar_hw		isar;
};

static LIST_HEAD(Cards);
static DEFINE_RWLOCK(card_lock); /* protect Cards */

static void
_set_debug(struct sfax_hw *card)
{
	card->isac.dch.debug = debug;
	card->isar.ch[0].bch.debug = debug;
	card->isar.ch[1].bch.debug = debug;
}

static int
set_debug(const char *val, struct kernel_param *kp)
{
	int ret;
	struct sfax_hw *card;

	ret = param_set_uint(val, kp);
	if (!ret) {
		read_lock(&card_lock);
		list_for_each_entry(card, &Cards, list)
			_set_debug(card);
		read_unlock(&card_lock);
	}
	return ret;
}

MODULE_AUTHOR("Karsten Keil");
MODULE_LICENSE("GPL v2");
MODULE_VERSION(SPEEDFAX_REV);
MODULE_FIRMWARE("isdn/ISAR.BIN");
module_param_call(debug, set_debug, param_get_uint, &debug, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Speedfax debug mask");
module_param(irqloops, uint, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(irqloops, "Speedfax maximal irqloops (default 4)");

IOFUNC_IND(ISAC, sfax_hw, p_isac)
IOFUNC_IND(ISAR, sfax_hw, p_isar)

static irqreturn_t
speedfax_irq(int intno, void *dev_id)
{
	struct sfax_hw	*sf = dev_id;
	u8 val;
	int cnt = irqloops;

	spin_lock(&sf->lock);
	val = inb(sf->cfg + TIGER_AUX_STATUS);
	if (val & SFAX_TIGER_IRQ_BIT) { /* for us or shared ? */
		spin_unlock(&sf->lock);
		return IRQ_NONE; /* shared */
	}
	sf->irqcnt++;
	val = ReadISAR_IND(sf, ISAR_IRQBIT);
Start_ISAR:
	if (val & ISAR_IRQSTA)
		mISDNisar_irq(&sf->isar);
	val = ReadISAC_IND(sf, ISAC_ISTA);
	if (val)
		mISDNisac_irq(&sf->isac, val);
	val = ReadISAR_IND(sf, ISAR_IRQBIT);
	if ((val & ISAR_IRQSTA) && cnt--)
		goto Start_ISAR;
	if (cnt < irqloops)
		pr_debug("%s: %d irqloops cpu%d\n", sf->name,
			 irqloops - cnt, smp_processor_id());
	if (irqloops && !cnt)
		pr_notice("%s: %d IRQ LOOP cpu%d\n", sf->name,
			  irqloops, smp_processor_id());
	spin_unlock(&sf->lock);
	return IRQ_HANDLED;
}

static void
enable_hwirq(struct sfax_hw *sf)
{
	WriteISAC_IND(sf, ISAC_MASK, 0);
	WriteISAR_IND(sf, ISAR_IRQBIT, ISAR_IRQMSK);
	outb(SFAX_TIGER_IRQ_BIT, sf->cfg + TIGER_AUX_IRQMASK);
}

static void
disable_hwirq(struct sfax_hw *sf)
{
	WriteISAC_IND(sf, ISAC_MASK, 0xFF);
	WriteISAR_IND(sf, ISAR_IRQBIT, 0);
	outb(0, sf->cfg + TIGER_AUX_IRQMASK);
}

static void
reset_speedfax(struct sfax_hw *sf)
{

	pr_debug("%s: resetting card\n", sf->name);
	outb(TIGER_EXTERN_RESET_ON, sf->cfg + TIGER_RESET_ADDR);
	outb(SFAX_PCI_RESET_ON, sf->cfg + TIGER_AUX_DATA);
	mdelay(1);
	outb(TIGER_EXTERN_RESET_OFF, sf->cfg + TIGER_RESET_ADDR);
	sf->aux_data = SFAX_PCI_RESET_OFF;
	outb(sf->aux_data, sf->cfg + TIGER_AUX_DATA);
	mdelay(1);
}

static int
sfax_ctrl(struct sfax_hw  *sf, u32 cmd, u_long arg)
{
	int ret = 0;

	switch (cmd) {
	case HW_RESET_REQ:
		reset_speedfax(sf);
		break;
	case HW_ACTIVATE_IND:
		if (arg & 1)
			sf->aux_data &= ~SFAX_LED1_BIT;
		if (arg & 2)
			sf->aux_data &= ~SFAX_LED2_BIT;
		outb(sf->aux_data, sf->cfg + TIGER_AUX_DATA);
		break;
	case HW_DEACT_IND:
		if (arg & 1)
			sf->aux_data |= SFAX_LED1_BIT;
		if (arg & 2)
			sf->aux_data |= SFAX_LED2_BIT;
		outb(sf->aux_data, sf->cfg + TIGER_AUX_DATA);
		break;
	default:
		pr_info("%s: %s unknown command %x %lx\n",
			sf->name, __func__, cmd, arg);
		ret = -EINVAL;
		break;
	}
	return ret;
}

static int
channel_ctrl(struct sfax_hw  *sf, struct mISDN_ctrl_req *cq)
{
	int	ret = 0;

	switch (cq->op) {
	case MISDN_CTRL_GETOP:
		cq->op = MISDN_CTRL_LOOP | MISDN_CTRL_L1_TIMER3;
		break;
	case MISDN_CTRL_LOOP:
		/* cq->channel: 0 disable, 1 B1 loop 2 B2 loop, 3 both */
		if (cq->channel < 0 || cq->channel > 3) {
			ret = -EINVAL;
			break;
		}
		ret = sf->isac.ctrl(&sf->isac, HW_TESTLOOP, cq->channel);
		break;
	case MISDN_CTRL_L1_TIMER3:
		ret = sf->isac.ctrl(&sf->isac, HW_TIMER3_VALUE, cq->p1);
		break;
	default:
		pr_info("%s: unknown Op %x\n", sf->name, cq->op);
		ret = -EINVAL;
		break;
	}
	return ret;
}

static int
sfax_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
{
	struct mISDNdevice	*dev = container_of(ch, struct mISDNdevice, D);
	struct dchannel		*dch = container_of(dev, struct dchannel, dev);
	struct sfax_hw		*sf = dch->hw;
	struct channel_req	*rq;
	int			err = 0;

	pr_debug("%s: cmd:%x %p\n", sf->name, cmd, arg);
	switch (cmd) {
	case OPEN_CHANNEL:
		rq = arg;
		if (rq->protocol == ISDN_P_TE_S0)
			err = sf->isac.open(&sf->isac, rq);
		else
			err = sf->isar.open(&sf->isar, rq);
		if (err)
			break;
		if (!try_module_get(THIS_MODULE))
			pr_info("%s: cannot get module\n", sf->name);
		break;
	case CLOSE_CHANNEL:
		pr_debug("%s: dev(%d) close from %p\n", sf->name,
			 dch->dev.id, __builtin_return_address(0));
		module_put(THIS_MODULE);
		break;
	case CONTROL_CHANNEL:
		err = channel_ctrl(sf, arg);
		break;
	default:
		pr_debug("%s: unknown command %x\n", sf->name, cmd);
		return -EINVAL;
	}
	return err;
}

static int __devinit
init_card(struct sfax_hw *sf)
{
	int	ret, cnt = 3;
	u_long	flags;

	ret = request_irq(sf->irq, speedfax_irq, IRQF_SHARED, sf->name, sf);
	if (ret) {
		pr_info("%s: couldn't get interrupt %d\n", sf->name, sf->irq);
		return ret;
	}
	while (cnt--) {
		spin_lock_irqsave(&sf->lock, flags);
		ret = sf->isac.init(&sf->isac);
		if (ret) {
			spin_unlock_irqrestore(&sf->lock, flags);
			pr_info("%s: ISAC init failed with %d\n",
				sf->name, ret);
			break;
		}
		enable_hwirq(sf);
		/* RESET Receiver and Transmitter */
		WriteISAC_IND(sf, ISAC_CMDR, 0x41);
		spin_unlock_irqrestore(&sf->lock, flags);
		msleep_interruptible(10);
		if (debug & DEBUG_HW)
			pr_notice("%s: IRQ %d count %d\n", sf->name,
				  sf->irq, sf->irqcnt);
		if (!sf->irqcnt) {
			pr_info("%s: IRQ(%d) got no requests during init %d\n",
				sf->name, sf->irq, 3 - cnt);
		} else
			return 0;
	}
	free_irq(sf->irq, sf);
	return -EIO;
}


static int __devinit
setup_speedfax(struct sfax_hw *sf)
{
	u_long flags;

	if (!request_region(sf->cfg, 256, sf->name)) {
		pr_info("mISDN: %s config port %x-%x already in use\n",
			sf->name, sf->cfg, sf->cfg + 255);
		return -EIO;
	}
	outb(0xff, sf->cfg);
	outb(0, sf->cfg);
	outb(0xdd, sf->cfg + TIGER_AUX_CTRL);
	outb(0, sf->cfg + TIGER_AUX_IRQMASK);

	sf->isac.type = IPAC_TYPE_ISAC;
	sf->p_isac.ale = sf->cfg + SFAX_PCI_ADDR;
	sf->p_isac.port = sf->cfg + SFAX_PCI_ISAC;
	sf->p_isar.ale = sf->cfg + SFAX_PCI_ADDR;
	sf->p_isar.port = sf->cfg + SFAX_PCI_ISAR;
	ASSIGN_FUNC(IND, ISAC, sf->isac);
	ASSIGN_FUNC(IND, ISAR, sf->isar);
	spin_lock_irqsave(&sf->lock, flags);
	reset_speedfax(sf);
	disable_hwirq(sf);
	spin_unlock_irqrestore(&sf->lock, flags);
	return 0;
}

static void
release_card(struct sfax_hw *card) {
	u_long	flags;

	spin_lock_irqsave(&card->lock, flags);
	disable_hwirq(card);
	spin_unlock_irqrestore(&card->lock, flags);
	card->isac.release(&card->isac);
	free_irq(card->irq, card);
	card->isar.release(&card->isar);
	mISDN_unregister_device(&card->isac.dch.dev);
	release_region(card->cfg, 256);
	pci_disable_device(card->pdev);
	pci_set_drvdata(card->pdev, NULL);
	write_lock_irqsave(&card_lock, flags);
	list_del(&card->list);
	write_unlock_irqrestore(&card_lock, flags);
	kfree(card);
	sfax_cnt--;
}

static int __devinit
setup_instance(struct sfax_hw *card)
{
	const struct firmware *firmware;
	int i, err;
	u_long flags;

	snprintf(card->name, MISDN_MAX_IDLEN - 1, "Speedfax.%d", sfax_cnt + 1);
	write_lock_irqsave(&card_lock, flags);
	list_add_tail(&card->list, &Cards);
	write_unlock_irqrestore(&card_lock, flags);
	_set_debug(card);
	spin_lock_init(&card->lock);
	card->isac.hwlock = &card->lock;
	card->isar.hwlock = &card->lock;
	card->isar.ctrl = (void *)&sfax_ctrl;
	card->isac.name = card->name;
	card->isar.name = card->name;
	card->isar.owner = THIS_MODULE;

	err = request_firmware(&firmware, "isdn/ISAR.BIN", &card->pdev->dev);
	if (err < 0) {
		pr_info("%s: firmware request failed %d\n",
			card->name, err);
		goto error_fw;
	}
	if (debug & DEBUG_HW)
		pr_notice("%s: got firmware %zu bytes\n",
			  card->name, firmware->size);

	mISDNisac_init(&card->isac, card);

	card->isac.dch.dev.D.ctrl = sfax_dctrl;
	card->isac.dch.dev.Bprotocols =
		mISDNisar_init(&card->isar, card);
	for (i = 0; i < 2; i++) {
		set_channelmap(i + 1, card->isac.dch.dev.channelmap);
		list_add(&card->isar.ch[i].bch.ch.list,
			 &card->isac.dch.dev.bchannels);
	}

	err = setup_speedfax(card);
	if (err)
		goto error_setup;
	err = card->isar.init(&card->isar);
	if (err)
		goto error;
	err = mISDN_register_device(&card->isac.dch.dev,
				    &card->pdev->dev, card->name);
	if (err)
		goto error;
	err = init_card(card);
	if (err)
		goto error_init;
	err = card->isar.firmware(&card->isar, firmware->data, firmware->size);
	if (!err)  {
		release_firmware(firmware);
		sfax_cnt++;
		pr_notice("SpeedFax %d cards installed\n", sfax_cnt);
		return 0;
	}
	disable_hwirq(card);
	free_irq(card->irq, card);
error_init:
	mISDN_unregister_device(&card->isac.dch.dev);
error:
	release_region(card->cfg, 256);
error_setup:
	card->isac.release(&card->isac);
	card->isar.release(&card->isar);
	release_firmware(firmware);
error_fw:
	pci_disable_device(card->pdev);
	write_lock_irqsave(&card_lock, flags);
	list_del(&card->list);
	write_unlock_irqrestore(&card_lock, flags);
	kfree(card);
	return err;
}

static int __devinit
sfaxpci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
	int err = -ENOMEM;
	struct sfax_hw *card = kzalloc(sizeof(struct sfax_hw), GFP_KERNEL);

	if (!card) {
		pr_info("No memory for Speedfax+ PCI\n");
		return err;
	}
	card->pdev = pdev;
	err = pci_enable_device(pdev);
	if (err) {
		kfree(card);
		return err;
	}

	pr_notice("mISDN: Speedfax found adapter %s at %s\n",
		  (char *)ent->driver_data, pci_name(pdev));

	card->cfg = pci_resource_start(pdev, 0);
	card->irq = pdev->irq;
	pci_set_drvdata(pdev, card);
	err = setup_instance(card);
	if (err)
		pci_set_drvdata(pdev, NULL);
	return err;
}

static void __devexit
sfax_remove_pci(struct pci_dev *pdev)
{
	struct sfax_hw	*card = pci_get_drvdata(pdev);

	if (card)
		release_card(card);
	else
		pr_debug("%s: drvdata already removed\n", __func__);
}

static struct pci_device_id sfaxpci_ids[] __devinitdata = {
	{ PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100,
	  PCI_SUBVENDOR_SPEEDFAX_PYRAMID, PCI_SUB_ID_SEDLBAUER,
	  0, 0, (unsigned long) "Pyramid Speedfax + PCI"
	},
	{ PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100,
	  PCI_SUBVENDOR_SPEEDFAX_PCI, PCI_SUB_ID_SEDLBAUER,
	  0, 0, (unsigned long) "Sedlbauer Speedfax + PCI"
	},
	{ }
};
MODULE_DEVICE_TABLE(pci, sfaxpci_ids);

static struct pci_driver sfaxpci_driver = {
	.name = "speedfax+ pci",
	.probe = sfaxpci_probe,
	.remove = __devexit_p(sfax_remove_pci),
	.id_table = sfaxpci_ids,
};

static int __init
Speedfax_init(void)
{
	int err;

	pr_notice("Sedlbauer Speedfax+ Driver Rev. %s\n",
		  SPEEDFAX_REV);
	err = pci_register_driver(&sfaxpci_driver);
	return err;
}

static void __exit
Speedfax_cleanup(void)
{
	pci_unregister_driver(&sfaxpci_driver);
}

module_init(Speedfax_init);
module_exit(Speedfax_cleanup);
