/*
 * Copyright (C) 2008 Per Dalen <per.dalen@cnw.se>
 *
 * Parts of this software are based on (derived) the following:
 *
 * - Kvaser linux driver, version 4.72 BETA
 *   Copyright (C) 2002-2007 KVASER AB
 *
 * - Lincan driver, version 0.3.3, OCERA project
 *   Copyright (C) 2004 Pavel Pisa
 *   Copyright (C) 2001 Arnaud Westenberg
 *
 * - Socketcan SJA1000 drivers
 *   Copyright (C) 2007 Wolfgang Grandegger <wg@grandegger.com>
 *   Copyright (c) 2002-2007 Volkswagen Group Electronic Research
 *   Copyright (c) 2003 Matthias Brukner, Trajet Gmbh, Rebenring 33,
 *   38106 Braunschweig, GERMANY
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the version 2 of the GNU General Public License
 * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/netdevice.h>
#include <linux/delay.h>
#include <linux/pci.h>
#include <linux/can/dev.h>
#include <linux/io.h>

#include "sja1000.h"

#define DRV_NAME  "kvaser_pci"

MODULE_AUTHOR("Per Dalen <per.dalen@cnw.se>");
MODULE_DESCRIPTION("Socket-CAN driver for KVASER PCAN PCI cards");
MODULE_SUPPORTED_DEVICE("KVASER PCAN PCI CAN card");
MODULE_LICENSE("GPL v2");

#define MAX_NO_OF_CHANNELS        4 /* max no of channels on a single card */

struct kvaser_pci {
	int channel;
	struct pci_dev *pci_dev;
	struct net_device *slave_dev[MAX_NO_OF_CHANNELS-1];
	void __iomem *conf_addr;
	void __iomem *res_addr;
	int no_channels;
	u8 xilinx_ver;
};

#define KVASER_PCI_CAN_CLOCK      (16000000 / 2)

/*
 * The board configuration is probably following:
 * RX1 is connected to ground.
 * TX1 is not connected.
 * CLKO is not connected.
 * Setting the OCR register to 0xDA is a good idea.
 * This means  normal output mode , push-pull and the correct polarity.
 */
#define KVASER_PCI_OCR            (OCR_TX0_PUSHPULL | OCR_TX1_PUSHPULL)

/*
 * In the CDR register, you should set CBP to 1.
 * You will probably also want to set the clock divider value to 0
 * (meaning divide-by-2), the Pelican bit, and the clock-off bit
 * (you will have no need for CLKOUT anyway).
 */
#define KVASER_PCI_CDR            (CDR_CBP | CDR_CLKOUT_MASK)

/*
 * These register values are valid for revision 14 of the Xilinx logic.
 */
#define XILINX_VERINT             7   /* Lower nibble simulate interrupts,
					 high nibble version number. */

#define XILINX_PRESUMED_VERSION   14

/*
 * Important S5920 registers
 */
#define S5920_INTCSR              0x38
#define S5920_PTCR                0x60
#define INTCSR_ADDON_INTENABLE_M  0x2000


#define KVASER_PCI_PORT_BYTES     0x20

#define PCI_CONFIG_PORT_SIZE      0x80      /* size of the config io-memory */
#define PCI_PORT_SIZE             0x80      /* size of a channel io-memory */
#define PCI_PORT_XILINX_SIZE      0x08      /* size of a xilinx io-memory */

#define KVASER_PCI_VENDOR_ID1     0x10e8    /* the PCI device and vendor IDs */
#define KVASER_PCI_DEVICE_ID1     0x8406

#define KVASER_PCI_VENDOR_ID2     0x1a07    /* the PCI device and vendor IDs */
#define KVASER_PCI_DEVICE_ID2     0x0008

static DEFINE_PCI_DEVICE_TABLE(kvaser_pci_tbl) = {
	{KVASER_PCI_VENDOR_ID1, KVASER_PCI_DEVICE_ID1, PCI_ANY_ID, PCI_ANY_ID,},
	{KVASER_PCI_VENDOR_ID2, KVASER_PCI_DEVICE_ID2, PCI_ANY_ID, PCI_ANY_ID,},
	{ 0,}
};

MODULE_DEVICE_TABLE(pci, kvaser_pci_tbl);

static u8 kvaser_pci_read_reg(const struct sja1000_priv *priv, int port)
{
	return ioread8(priv->reg_base + port);
}

static void kvaser_pci_write_reg(const struct sja1000_priv *priv,
				 int port, u8 val)
{
	iowrite8(val, priv->reg_base + port);
}

static void kvaser_pci_disable_irq(struct net_device *dev)
{
	struct sja1000_priv *priv = netdev_priv(dev);
	struct kvaser_pci *board = priv->priv;
	u32 intcsr;

	/* Disable interrupts from card */
	intcsr = ioread32(board->conf_addr + S5920_INTCSR);
	intcsr &= ~INTCSR_ADDON_INTENABLE_M;
	iowrite32(intcsr, board->conf_addr + S5920_INTCSR);
}

static void kvaser_pci_enable_irq(struct net_device *dev)
{
	struct sja1000_priv *priv = netdev_priv(dev);
	struct kvaser_pci *board = priv->priv;
	u32 tmp_en_io;

	/* Enable interrupts from card */
	tmp_en_io = ioread32(board->conf_addr + S5920_INTCSR);
	tmp_en_io |= INTCSR_ADDON_INTENABLE_M;
	iowrite32(tmp_en_io, board->conf_addr + S5920_INTCSR);
}

static int number_of_sja1000_chip(void __iomem *base_addr)
{
	u8 status;
	int i;

	for (i = 0; i < MAX_NO_OF_CHANNELS; i++) {
		/* reset chip */
		iowrite8(MOD_RM, base_addr +
			 (i * KVASER_PCI_PORT_BYTES) + SJA1000_MOD);
		status = ioread8(base_addr +
				 (i * KVASER_PCI_PORT_BYTES) + SJA1000_MOD);
		/* check reset bit */
		if (!(status & MOD_RM))
			break;
	}

	return i;
}

static void kvaser_pci_del_chan(struct net_device *dev)
{
	struct sja1000_priv *priv;
	struct kvaser_pci *board;
	int i;

	if (!dev)
		return;
	priv = netdev_priv(dev);
	board = priv->priv;
	if (!board)
		return;

	dev_info(&board->pci_dev->dev, "Removing device %s\n",
		 dev->name);

	/* Disable PCI interrupts */
	kvaser_pci_disable_irq(dev);

	for (i = 0; i < board->no_channels - 1; i++) {
		if (board->slave_dev[i]) {
			dev_info(&board->pci_dev->dev, "Removing device %s\n",
				 board->slave_dev[i]->name);
			unregister_sja1000dev(board->slave_dev[i]);
			free_sja1000dev(board->slave_dev[i]);
		}
	}
	unregister_sja1000dev(dev);

	pci_iounmap(board->pci_dev, priv->reg_base);
	pci_iounmap(board->pci_dev, board->conf_addr);
	pci_iounmap(board->pci_dev, board->res_addr);

	free_sja1000dev(dev);
}

static int kvaser_pci_add_chan(struct pci_dev *pdev, int channel,
			       struct net_device **master_dev,
			       void __iomem *conf_addr,
			       void __iomem *res_addr,
			       void __iomem *base_addr)
{
	struct net_device *dev;
	struct sja1000_priv *priv;
	struct kvaser_pci *board;
	int err, init_step;

	dev = alloc_sja1000dev(sizeof(struct kvaser_pci));
	if (dev == NULL)
		return -ENOMEM;

	priv = netdev_priv(dev);
	board = priv->priv;

	board->pci_dev = pdev;
	board->channel = channel;

	/* S5920 */
	board->conf_addr = conf_addr;

	/* XILINX board wide address */
	board->res_addr = res_addr;

	if (channel == 0) {
		board->xilinx_ver =
			ioread8(board->res_addr + XILINX_VERINT) >> 4;
		init_step = 2;

		/* Assert PTADR# - we're in passive mode so the other bits are
		   not important */
		iowrite32(0x80808080UL, board->conf_addr + S5920_PTCR);

		/* Enable interrupts from card */
		kvaser_pci_enable_irq(dev);
	} else {
		struct sja1000_priv *master_priv = netdev_priv(*master_dev);
		struct kvaser_pci *master_board = master_priv->priv;
		master_board->slave_dev[channel - 1] = dev;
		master_board->no_channels = channel + 1;
		board->xilinx_ver = master_board->xilinx_ver;
	}

	priv->reg_base = base_addr + channel * KVASER_PCI_PORT_BYTES;

	priv->read_reg = kvaser_pci_read_reg;
	priv->write_reg = kvaser_pci_write_reg;

	priv->can.clock.freq = KVASER_PCI_CAN_CLOCK;

	priv->ocr = KVASER_PCI_OCR;
	priv->cdr = KVASER_PCI_CDR;

	priv->irq_flags = IRQF_SHARED;
	dev->irq = pdev->irq;

	init_step = 4;

	dev_info(&pdev->dev, "reg_base=%p conf_addr=%p irq=%d\n",
		 priv->reg_base, board->conf_addr, dev->irq);

	SET_NETDEV_DEV(dev, &pdev->dev);

	/* Register SJA1000 device */
	err = register_sja1000dev(dev);
	if (err) {
		dev_err(&pdev->dev, "Registering device failed (err=%d)\n",
			err);
		goto failure;
	}

	if (channel == 0)
		*master_dev = dev;

	return 0;

failure:
	kvaser_pci_del_chan(dev);
	return err;
}

static int kvaser_pci_init_one(struct pci_dev *pdev,
			       const struct pci_device_id *ent)
{
	int err;
	struct net_device *master_dev = NULL;
	struct sja1000_priv *priv;
	struct kvaser_pci *board;
	int no_channels;
	void __iomem *base_addr = NULL;
	void __iomem *conf_addr = NULL;
	void __iomem *res_addr = NULL;
	int i;

	dev_info(&pdev->dev, "initializing device %04x:%04x\n",
		 pdev->vendor, pdev->device);

	err = pci_enable_device(pdev);
	if (err)
		goto failure;

	err = pci_request_regions(pdev, DRV_NAME);
	if (err)
		goto failure_release_pci;

	/* S5920 */
	conf_addr = pci_iomap(pdev, 0, PCI_CONFIG_PORT_SIZE);
	if (conf_addr == NULL) {
		err = -ENODEV;
		goto failure_release_regions;
	}

	/* XILINX board wide address */
	res_addr = pci_iomap(pdev, 2, PCI_PORT_XILINX_SIZE);
	if (res_addr == NULL) {
		err = -ENOMEM;
		goto failure_iounmap;
	}

	base_addr = pci_iomap(pdev, 1, PCI_PORT_SIZE);
	if (base_addr == NULL) {
		err = -ENOMEM;
		goto failure_iounmap;
	}

	no_channels = number_of_sja1000_chip(base_addr);
	if (no_channels == 0) {
		err = -ENOMEM;
		goto failure_iounmap;
	}

	for (i = 0; i < no_channels; i++) {
		err = kvaser_pci_add_chan(pdev, i, &master_dev,
					  conf_addr, res_addr,
					  base_addr);
		if (err)
			goto failure_cleanup;
	}

	priv = netdev_priv(master_dev);
	board = priv->priv;

	dev_info(&pdev->dev, "xilinx version=%d number of channels=%d\n",
		 board->xilinx_ver, board->no_channels);

	pci_set_drvdata(pdev, master_dev);
	return 0;

failure_cleanup:
	kvaser_pci_del_chan(master_dev);

failure_iounmap:
	if (conf_addr != NULL)
		pci_iounmap(pdev, conf_addr);
	if (res_addr != NULL)
		pci_iounmap(pdev, res_addr);
	if (base_addr != NULL)
		pci_iounmap(pdev, base_addr);

failure_release_regions:
	pci_release_regions(pdev);

failure_release_pci:
	pci_disable_device(pdev);

failure:
	return err;

}

static void kvaser_pci_remove_one(struct pci_dev *pdev)
{
	struct net_device *dev = pci_get_drvdata(pdev);

	kvaser_pci_del_chan(dev);

	pci_release_regions(pdev);
	pci_disable_device(pdev);
	pci_set_drvdata(pdev, NULL);
}

static struct pci_driver kvaser_pci_driver = {
	.name = DRV_NAME,
	.id_table = kvaser_pci_tbl,
	.probe = kvaser_pci_init_one,
	.remove = kvaser_pci_remove_one,
};

module_pci_driver(kvaser_pci_driver);
